feat(appkit): vendor TaskFlow engine and add TaskflowService skeleton#376
Draft
ditadi wants to merge 1 commit into
Draft
feat(appkit): vendor TaskFlow engine and add TaskflowService skeleton#376ditadi wants to merge 1 commit into
ditadi wants to merge 1 commit into
Conversation
Bootstraps a third core service (`this.taskflow`, peer of `this.cache` and `this.telemetry`) backed by the vendored Rust+napi engine at `packages/appkit/vendor/taskflow/`. The service is wired into the `CoreServiceRegistry` introduced in #374 so existing `createApp(...)` callers transparently gain durable execution plumbing, with an opt-out via `createApp({ taskflow: false })`. Scope of this PR (engine plumbing only): - Vendored binaries (`taskflow-darwin-arm64.node`, `taskflow-linux-x64.node`), the JS loader, type declarations, and `VENDOR.json` with SHA-256 digests for the optional integrity check (`APPKIT_VERIFY_TASKFLOW_VENDOR=1`). - `TaskflowService` wraps the vendor `Engine` with lifecycle hooks (`initialize`, `factory`, `shutdown`) and pass-through methods (`start`, `subscribe`, `reconnect`, `resume`, `stop`, `simulateCrash`). Default storage: SQLite at `.appkit/taskflow/`. Emits a `warn` on Databricks Apps + SQLite (multi-pod / ephemeral filesystem; tasks would not survive rolling restarts). - `Plugin` base class exposes `this.taskflow` (`TaskflowService | null`) and `requireTaskflow()` for the strict-mode caller. The deprecated `taskflow` legacy field on `BasePlugin.attachContext` lands here, paired with the same deprecation flags for `cache?` / `telemetry?` that the registry restructure (#374) already implied. - `ServerPlugin._gracefulShutdown` now consumes the `shutdownCoreServices` callback that `_createApp` already passes, draining cache/telemetry/taskflow through the registry. The SIGTERM/SIGINT re-entrancy guard is intentionally deferred to the hardening pass. - `tsdown.config.ts` copies the vendor files into `dist/appkit/vendor/` so the published package's emitted loader resolves the `.node` binary at the expected relative path. - `.gitignore` (root + dev-playground + template) excludes the per-machine SQLite/WAL files under `.appkit/`. - `knip.json` skips `packages/appkit/vendor/**` (vendored module exports are not consumed by AppKit's own code). Deliberately NOT in this PR (follow-up): - `task()` registration, `TaskDefinition`, `TypedTaskContext`, `TaskRef`, the `step()` helper. - `Plugin.executeTask` SSE bridge (the bridge file, `ActiveBridge`, `_registerBridge`, the shutdown drain loop). - Re-exports for `SseEvent`, `TASKFLOW_IK_HEADER`, `setupSseHeaders`, `writeSseFrame`, `ExecuteTaskSettings`. - The `tools/test-helpers.ts` stub service + SSE parser upgrade. - Analytics-plugin migration; durable-task example app. Plugins can call `this.taskflow.start(name, input)` and subscribe via `this.taskflow.subscribe(idempotencyKey)`, but no task can be defined yet — `task()` registration arrives with the typed surface in the next PR. Verified: pnpm -r typecheck, pnpm build, pnpm exec biome check, pnpm exec knip, full pnpm test (122 files, 2279 tests; +3 from #375) all green. Signed-off-by: ditadi <victordperd@gmail.com>
This was referenced May 11, 2026
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.
🥞 Stacked PR
Use this link to review incremental changes.
Bootstraps a third core service (
this.taskflow, peer ofthis.cacheandthis.telemetry) backed by the vendored Rust+napi engine atpackages/appkit/vendor/taskflow/. The service is wired into theCoreServiceRegistryintroduced in #374 so existingcreateApp(...)callers transparently gain durable execution plumbing, with an opt-out viacreateApp({ taskflow: false }).Scope of this PR (engine plumbing only)
taskflow-darwin-arm64.node,taskflow-linux-x64.node), the JS loader, type declarations, andVENDOR.jsonwith SHA-256 digests for the optional integrity check (APPKIT_VERIFY_TASKFLOW_VENDOR=1).TaskflowServicewraps the vendorEnginewith lifecycle hooks (initialize,factory,shutdown) and pass-through methods (start,subscribe,reconnect,resume,stop,simulateCrash). Default storage: SQLite at.appkit/taskflow/. Emits awarnon Databricks Apps + SQLite (multi-pod / ephemeral filesystem; tasks would not survive rolling restarts).Pluginbase class exposesthis.taskflow(TaskflowService | null) andrequireTaskflow()for the strict-mode caller. The deprecatedtaskflowlegacy field onBasePlugin.attachContextlands here, paired with the same deprecation flags forcache?/telemetry?that the registry restructure (refactor(appkit): introduce CoreServiceRegistry and ServiceLocator #374) already implied.ServerPlugin._gracefulShutdownnow consumes theshutdownCoreServicescallback that_createAppalready passes, draining cache/telemetry/taskflow through the registry. The SIGTERM/SIGINT re-entrancy guard is intentionally deferred to the hardening pass.tsdown.config.tscopies the vendor files intodist/appkit/vendor/so the published package's emitted loader resolves the.nodebinary at the expected relative path..gitignore(root + dev-playground + template) excludes the per-machine SQLite/WAL files under.appkit/.knip.jsonskipspackages/appkit/vendor/**(vendored module exports are not consumed by AppKit's own code).Deliberately NOT in this PR (follow-up)
task()registration,TaskDefinition,TypedTaskContext,TaskRef, thestep()helper.Plugin.executeTaskSSE bridge (the bridge file,ActiveBridge,_registerBridge, the shutdown drain loop).SseEvent,TASKFLOW_IK_HEADER,setupSseHeaders,writeSseFrame,ExecuteTaskSettings.tools/test-helpers.tsstub service + SSE parser upgrade.Plugins can call
this.taskflow.start(name, input)and subscribe viathis.taskflow.subscribe(idempotencyKey), but no task can be defined yet —task()registration arrives with the typed surface in the next PR.Verified:
pnpm -r typecheck,pnpm build,pnpm exec biome check,pnpm exec knip, fullpnpm test(122 files, 2279 tests; +3 from #375) all green.Signed-off-by: ditadi victordperd@gmail.com