Skip to content

feat(nexus-operations): DT-4005 standalone nexus operations API integrations#3444

Merged
rossedfort merged 4 commits into
DT-4001-SANOfrom
DT-4005-standalone-nexus-api-integrations
May 27, 2026
Merged

feat(nexus-operations): DT-4005 standalone nexus operations API integrations#3444
rossedfort merged 4 commits into
DT-4001-SANOfrom
DT-4005-standalone-nexus-api-integrations

Conversation

@rossedfort

Copy link
Copy Markdown
Contributor

Description & motivation 💭

Adds the API integration layer for the Standalone Nexus Operations feature — namespace-scoped Nexus operation executions invoked directly (not from workflows). This is Phase 1 of the Standalone Nexus Operations epic (DT-4001), mirroring the existing Standalone Activities pattern.

New files:

  • src/lib/types/nexus-operation-execution.ts — domain types: status enum, reuse/conflict policies, execution info (full + list subset), start request/response
  • src/lib/services/standalone-nexus-operations.ts — service functions: list (paginated), start, describe, poll (long-poll), cancel, terminate
  • src/lib/services/nexus-operation-counts.ts — count and count-by-status service functions
  • src/lib/stores/nexus-operations.ts — writable stores: refresh, loading, updating, count, error, query, searchParams
  • src/lib/utilities/standalone-nexus-operation-poller.svelte.tsStandaloneNexusOperationPoller class with initial fetch + continuous long-poll loop and AbortController teardown

Modified files:

  • src/lib/types/api.ts — adds operationId to APIRouteParameters; adds new nexus operation route path types
  • src/lib/utilities/route-for-api.ts — registers 6 new API routes: standalone-nexus-operations, standalone-nexus-operation, standalone-nexus-operation.poll, standalone-nexus-operation.cancel, standalone-nexus-operation.terminate, standalone-nexus-operations.count
  • src/lib/utilities/route-for.ts — adds 7 route helpers mirroring routeForStandaloneActivity*
  • src/lib/stores/filters.ts — adds nexusOperationFilters store

Key differences from Standalone Activities:

  • Input is a single Payload (not Payloads)
  • Routes use only operationId (no compound activityId/runId)
  • Supports both Cancel and Terminate (activities only have Terminate)
  • No retryPolicy field — server handles retries internally
  • idReusePolicy and idConflictPolicy are Nexus-specific enums
  • nexusHeader map for tracing propagation

Screenshots (if applicable) 📸

N/A — this PR is data/service layer only, no UI changes.

Design Considerations 🎨

None at this layer.

Testing 🧪

How was this tested 👻

  • Manual testing
  • E2E tests added
  • Unit tests added

Unit and integration tests are scoped to Phase 7 (DT-4007) after all feature phases ship. This PR is types/services/stores only with no rendered UI.

Steps for others to test: 🚶🏽‍♂️🚶🏽‍♀️

Type-check and lint pass with no regressions:

pnpm check   # should report 0 new errors (2 pre-existing errors in package/ dir unrelated to this PR)
pnpm lint    # should pass cleanly

Checklists

Draft Checklist

Merge Checklist

  • Phase 2 (DT-4006: feature flag + guard) merged first or this PR ships standalone as foundation

Issue(s) closed

DT-4005

Docs

No docs updates needed for this layer. Docs will be relevant when the list/detail pages ship.

@rossedfort rossedfort requested a review from a team as a code owner May 22, 2026 16:40
@vercel

vercel Bot commented May 22, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
holocene Ready Ready Preview, Comment May 27, 2026 4:17pm

Request Review

...(query ? { query } : {}),
},
request,
onError,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • ⚠️ Type 'ErrorCallback' is not assignable to type '(error: unknown, toasts?: Toaster, errors?: Writable<NetworkError | null>, isBrowser?: boolean) => void'.

}

if (formData.searchAttributes) {
searchAttributes = {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • ⚠️ Type '{ indexedFields?: ({ [k: string]: temporal.api.common.v1.IPayload; } | null); }' is not assignable to type '{ [k: string]: IPayload; }'.


if (formData.searchAttributes) {
searchAttributes = {
indexedFields: {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • ⚠️ Argument of type 'Record<string, unknown>[]' is not assignable to parameter of type '{ type: "Unspecified" | "Keyword" | "Text" | "Int" | "Double" | "Bool" | "KeywordList" | "Datetime"; label: string; value?: any; }[]'.

export class StandaloneNexusOperationPoller {
private abortController: AbortController;
private namespace: string;
private operationId: string;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • ⚠️ Property 'token' has no initializer and is not definitely assigned in the constructor.

this.namespace,
this.operationId,
);
} catch (error) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • ⚠️ Argument of type 'unknown' is not assignable to parameter of type 'Error'.

} catch (error) {
this.onError(error);
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • ⚠️ Argument of type 'NexusOperationExecution | undefined' is not assignable to parameter of type 'NexusOperationExecution'.


this.onUpdate(nexusOperationExecution);

if (

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • ⚠️ 'nexusOperationExecution' is possibly 'undefined'.

if (
nexusOperationExecution.info.status ===
'NEXUS_OPERATION_EXECUTION_STATUS_RUNNING'
) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • ⚠️ 'nexusOperationExecution' is possibly 'undefined'.
  • ⚠️ Type 'string | undefined' is not assignable to type 'string'.

if (
polledNexusOperationExecution &&
!isEmptyObject(polledNexusOperationExecution)
) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • ⚠️ Type 'string | undefined' is not assignable to type 'string'.

if (error instanceof Error && error.name === 'AbortError') {
return;
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • ⚠️ Argument of type 'unknown' is not assignable to parameter of type 'Error'.

@temporal-cicd

temporal-cicd Bot commented May 22, 2026

Copy link
Copy Markdown
Contributor
Warnings
⚠️

📊 Strict Mode: 11 errors in 2 files (1.2% of 919 total)

src/lib/services/standalone-nexus-operations.ts (3)
  • L58:6: Type 'ErrorCallback' is not assignable to type '(error: unknown, toasts?: Toaster, errors?: Writable<NetworkError | null>, isBrowser?: boolean) => void'.
  • L150:6: Type '{ indexedFields?: ({ [k: string]: temporal.api.common.v1.IPayload; } | null); }' is not assignable to type '{ [k: string]: IPayload; }'.
  • L151:31: Argument of type 'Record<string, unknown>[]' is not assignable to parameter of type '{ type: "Unspecified" | "Keyword" | "Text" | "Int" | "Double" | "Bool" | "KeywordList" | "Datetime"; label: string; value?: any; }[]'.
src/lib/utilities/standalone-nexus-operation-poller.svelte.ts (8)
  • L18:10: Property 'token' has no initializer and is not definitely assigned in the constructor.
  • L45:19: Argument of type 'unknown' is not assignable to parameter of type 'Error'.
  • L48:18: Argument of type 'NexusOperationExecution | undefined' is not assignable to parameter of type 'NexusOperationExecution'.
  • L51:6: 'nexusOperationExecution' is possibly 'undefined'.
  • L54:6: Type 'string | undefined' is not assignable to type 'string'.
  • L54:19: 'nexusOperationExecution' is possibly 'undefined'.
  • L70:12: Type 'string | undefined' is not assignable to type 'string'.
  • L78:23: Argument of type 'unknown' is not assignable to parameter of type 'Error'.

Generated by 🚫 dangerJS against 2d37d98

… operations

Adds NexusOperationExecution types, extends APIRouteParameters with operationId,
and registers 6 new API routes (list, describe/start, poll, cancel, terminate, count).
Adds route-for helpers mirroring the standalone activities pattern.

DT-4005
Adds fetchPaginatedNexusOperations, startStandaloneNexusOperation,
getNexusOperationExecution, pollNexusOperationExecution, cancel, and terminate.
Adds count and count-by-status service functions.

DT-4005
…e nexus operations

Adds nexus operation writable stores (refresh, loading, updating, count, error, query).
Adds StandaloneNexusOperationPoller with long-poll loop mirroring the activity poller.
Adds nexusOperationFilters store to filters.ts.

DT-4005
@rossedfort rossedfort force-pushed the DT-4005-standalone-nexus-api-integrations branch from a654b76 to 2d37d98 Compare May 27, 2026 16:16
@rossedfort rossedfort changed the base branch from main to DT-4001-SANO May 27, 2026 16:16
@rossedfort rossedfort merged commit 74ba1fb into DT-4001-SANO May 27, 2026
18 checks passed
@rossedfort rossedfort deleted the DT-4005-standalone-nexus-api-integrations branch May 27, 2026 20:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant