feat(core): factory-form Platform/Resource for parametric default exports#180
Open
sam-goodwin wants to merge 6 commits into
Open
feat(core): factory-form Platform/Resource for parametric default exports#180sam-goodwin wants to merge 6 commits into
sam-goodwin wants to merge 6 commits into
Conversation
`Cloudflare.state({ workerName })` was a no-op — the prop flowed into
existence checks and the deploy stage but never reached the deployed
worker's name or the post-deploy login probe, so a custom name would
deploy under `alchemy-state-store` and login would always look up the
default URL.
- `Api` is now `(scriptName) => Worker(...)` instead of a hardcoded
default-exported Worker, so the deployed worker honors the prop.
- `loginWithCloudflare` takes a `scriptName` and uses it for both the
edge-preview secret probe and the workers.dev URL derivation.
- All three callers thread `scriptName` through.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Contributor
|
Install the packages built from this commit: alchemy bun add alchemy@https://pkg.ing/alchemy/af49738@alchemy.run/better-auth bun add @alchemy.run/better-auth@https://pkg.ing/@alchemy.run/better-auth/af49738@alchemy.run/pr-package bun add @alchemy.run/pr-package@https://pkg.ing/@alchemy.run/pr-package/af49738 |
…orts
Adds an overload so a Platform-style resource (Worker, Container, Lambda…)
or a plain Resource can be defined as a function:
export default Worker((scriptName: string) =>
Worker("Api", { name: scriptName, main: import.meta.filename, ... }, body));
At deploy time `yield* MyWorker(...args)` runs the inner Effect and
stamps the args into `Props.env` under `__ALCHEMY_FACTORY_ARGS__`,
riding the existing env-binding lifecycle as a `plain_text` binding.
At runtime, the generated Cloudflare Worker entrypoint detects the
`__alchemyFactory` marker on the imported default export, JSON-decodes
the args from `env`, and calls the function before treating the
result as a Layer/Effect.
v1 limitation: factory args must be JSON-serializable. Output /
Redacted args TODO.
Updates `Cloudflare/StateStore/Api.ts` to use the factory form so
`Cloudflare.state({ workerName })` actually deploys/looks up the
custom worker name end-to-end.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Switch from a single combined JSON binding to per-arg bindings. Each arg lands at \`__ALCHEMY_FACTORY_ARG_<i>__\` with a count at \`__ALCHEMY_FACTORY_ARG_COUNT__\`. Top-level Redacted args ride \`secret_text\` via the same JSON-with-\`_tag: "Redacted"\`-marker encoding \`ctx.set\`/\`ctx.get\` already use; Output args resolve at deploy time, so \`Output<Redacted<string>>\` lands on \`secret_text\` too. Generated entrypoint decodes per arg and rebuilds the Redacted wrapper before calling the factory. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The previous shape \`Worker((args) => Worker("Api", ...))\` repeats the
\`Worker\` token at both ends with two different meanings — outer is
the factory wrapper, inner is the actual resource constructor. Switch
the inner side to a tuple so the factory returns the same positional
shape the constructor already accepts:
export default Worker((scriptName: string) => [
"Api",
{ name: scriptName, main: import.meta.filename, ... },
Effect.gen(function* () { ... }),
]);
The wrapper applies the tuple to the constructor itself; the args
persistence is unchanged. Resource (non-Platform) gets the same
treatment with a 2-tuple \`[id, props]\`.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Six tests covering the deploy-time encode and a runtime-side decode
that mirrors the generated worker entrypoint:
- marker exposed on the wrapper
- plain args land as JSON-encoded plain_text bindings under
__ALCHEMY_FACTORY_ARG_<i>__ + __ALCHEMY_FACTORY_ARG_COUNT__
- Redacted args stay Redacted in env so the lifecycle binds
secret_text, with the JSON \`_tag: "Redacted"\` marker preserved
- Output args pass through as Output for the engine resolver to
unwrap at deploy time
- decode round-trip rebuilds Redacted and primitives
- makeFactory (the shared helper used by both Platform and Resource
overloads) attaches the marker and stamps the args
Reorders the factory overload before the methods overload in
ResourceConstructor — TS overload resolution picks the first match,
and a function value also satisfies \`{ [key: string]: any }\`.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Adds a factory overload for Platform/Resource so a default-exported worker can be parametric, and uses it to fix
Cloudflare.state({ workerName })end-to-end.The factory function returns the same
[id, props, body]tuple the positionalWorker(id, props, body)form accepts — no nestedWorker(...Worker(...)).Resource(non-Platform) takes a[id, props]2-tuple.At deploy time,
yield* MyWorker(...args)applies the tuple to the constructor and stamps each arg intoProps.envas its own binding (__ALCHEMY_FACTORY_ARG_<i>__, plus__ALCHEMY_FACTORY_ARG_COUNT__). Top-levelRedactedargs ride thesecret_textlifecycle; everything else ridesplain_text.Outputargs resolve at deploy time via the engine's normal Output resolver, soOutput<Redacted<string>>lands onsecret_texttoo — same encoding as the existingctx.set/ctx.getpair.Cloudflare/StateStore/Api.tsswitches to the factory form. Combined with the existingloginWithCloudflare(scriptName)change,Cloudflare.state({ workerName: "custom-state" })now deploys and looks upcustom-state— the bug that motivated this work.🤖 Generated with Claude Code