[pull] main from vercel:main#395
Merged
Merged
Conversation
* docs: document run idempotency
* docs: address idempotency review feedback
* docs: make hook tokens the idempotency pattern
* docs: address toolbar idempotency feedback
* docs: clarify idempotency page description
* docs: scope idempotency descriptions
* docs: move step idempotency example under section
* docs: simplify idempotency guidance
* docs: simplify idempotency cookbook
* docs: add empty changeset
Signed-off-by: Nathan Rajlich <n@n8.io>
* docs: address idempotency review feedback
* feat: add hook ready promise
* docs: mention conflicting hook run id
* test: cover hook ready continuation scheduling
* feat: replace hook.ready with hook.hasConflict (Promise<boolean>)
- hook.hasConflict resolves true when the token is owned by another
active hook, false once registration is committed — no throw, so
workflows can branch on conflicts early. Awaiting it suspends the
workflow to commit the hook registration (createHook alone does not).
- Chain the already-created fast-path through promiseQueue so
resolution order matches event-log order (review feedback).
- Skip inline step execution when a suspension has an awaited hook
creation so the hasConflict continuation can advance independently
of step execution (review feedback).
- Update unit tests, e2e tests, workbench workflows, and v4/v5 docs.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* docs: fix inconsistent hasConflict bullet in create-webhook reference
State both resolution values explicitly (true = token already owned,
false = registered) instead of a parenthetical that only described the
false case.
* docs: require docs preview links in PR descriptions for docs changes
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* docs: restore SWC Plugin heading in AGENTS.md
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* docs: adopt hook.hasConflict in run idempotency docs
- Primary claim pattern is now `if (await hook.hasConflict)` instead of
try/catch on HookConflictError; payload awaits still reject with
HookConflictError (with conflictingRunId) when the owner's run ID is
needed.
- Route example returns the active owner via resumeHook()'s runId
instead of threading conflictingRunId through the workflow result.
- Update claim-pattern prose across start(), getHookByToken(), world
storage, scheduling, workflow composition, and cookbook idempotency
pages (v4 + v5).
- Add @skip-typecheck marker to the cross-block route sample, fixing a
pre-existing docs typecheck failure.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* docs: move resume-or-start guidance into a dedicated resumeHook example
The early callout was too vague and out of place at the top of the API
reference. Replace it with a 'Resume or Start' example section that
explains the flow, shows the resume-first/start-then-retry route, and
links to the run idempotency pattern.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* docs: detect the concurrent-start race via runId comparison instead of awaiting returnValue
The 'Resume or Start' example returned the just-started run's runId with
reused: false even when a concurrent request's run won the token race —
the payload had reached the actual owner, so the response pointed callers
at a run that exits as a duplicate. The foundations route handled the
race correctly but by awaiting run.returnValue, blocking the HTTP
response on full workflow completion.
resumeHook() always resolves against the actual active owner, so
comparing the resumed hook's runId with the started run's runId detects
the race in both examples — race-correct and non-blocking.
* feat: replace hook.hasConflict with hook.getConflict (Promise<Run | null>)
hasConflict's boolean didn't expose WHICH run owns the token, so the
duplicate run couldn't act on the conflict. getConflict resolves with
null once registration commits, or with a Run handle for the conflicting
run — letting the workflow return/log the owner's runId, inspect its
status, await its result, or cancel it and continue, all in code.
The workflow-mode create-hook module exposes the bundle's compiled Run
class (durable step-proxy methods) on a well-known symbol so the host-
side hook consumer can construct the conflicting run inside the VM.
Contexts without the class (plain unit tests) fall back to a { runId }
object, which is also the documented v4 shape (no native Run
serialization in v4).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* docs: adopt hook.getConflict and add conflict-handling strategy guide
Run idempotency docs now use getConflict (resolves with the conflicting
Run in v5, { runId } in v4) and document code-driven conflict strategies
in place of static ID-reuse policies: reject the duplicate, adopt the
owner's result, inspect before deciding, signal the owner via
resumeHook, and supersede via cancel-and-reclaim.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* fix: never resolve getConflict with a non-Run fallback shape
getConflict's contract is Promise<Run | null>. In the degenerate cases
where a real Run cannot be constructed — a hook_conflict event persisted
by an old world without conflictingRunId, or a context that never loaded
the workflow-mode create-hook module — reject with HookConflictError
instead of resolving with a { runId }-shaped impostor.
Test harnesses now register the Run class on the (VM) globalThis like
real bundles do.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* refactor: make getConflict a method — hook.getConflict()
A property getter that triggers registration/suspension reads as passive
state; a method makes the side effect explicit. Update implementation,
types, tests, e2e workflows, docs, and changeset.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* docs: getConflict is a method — hook.getConflict()
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* docs: typecheck every sample — drop skip-typecheck escape hatches
Route examples typecheck as-is since the runId-comparison rewrite;
strategy fragments are now complete self-contained workflows; the
publishing-libraries cross-block dependency uses the declare @setup
convention. 934 samples typechecked, none skipped by this PR.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* review: guard Run class registration, fix anchors, clarify changeset
- Only register WORKFLOW_RUN_CLASS when the workflow runtime is present
(WORKFLOW_CREATE_HOOK installed on globalThis), so host imports of the
workflow-mode module neither mutate the host global nor expose the
non-step-proxy host Run.
- Drop #run-idempotency link fragments — that section lands in the
stacked docs PR (#2011), which restores the anchored links.
- Note in docs that getConflict() rejects with HookConflictError for
legacy hook_conflict events lacking the owner's run ID.
- Changeset now calls out the hasConflict -> getConflict() replacement.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* docs: restore run-idempotency anchors now that the section exists here
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* docs: describe fixed conflict policies generically, without naming other systems
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
---------
Signed-off-by: Nathan Rajlich <n@n8.io>
Co-authored-by: Nathan Rajlich <n@n8.io>
Co-authored-by: Peter Wielander <mittgfu@gmail.com>
Co-authored-by: Claude Fable 5 <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 subscribe to this conversation on GitHub.
Already have an account?
Sign in.
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.
See Commits and Changes for more details.
Created by
pull[bot] (v2.0.0-alpha.4)
Can you help keep this open source service alive? 💖 Please sponsor : )