Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .scripts/list-of-samples.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
"nexus-cancellation",
"nexus-hello",
"nexus-messaging",
"nexus-standalone-operations",
"patching-api",
"production",
"protobufs",
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ and you'll be given the list of sample options.

- [**Nexus Hello**](./nexus-hello): Demonstrates how to define a Nexus Service, implement the Operation handlers, and call the Operations from a Workflow.
- [**Nexus Cancellation**](./nexus-cancellation): Demonstrates how to cancel a Nexus Operation from a caller workflow using a CancellationScope
- [**Nexus Standalone Operations**](./nexus-standalone-operations): Execute Nexus Operations directly from a Temporal Client, without a caller Workflow.

#### Workflow APIs

Expand Down
4 changes: 2 additions & 2 deletions activities-examples/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
"@temporalio/testing": "^1.18.1",
"@tsconfig/node22": "^22.0.0",
"@types/jest": "^27.5.1",
"@types/mocha": "8.x",
"@types/mocha": "10.x",
"@types/node": "^22.9.1",
"@types/node-fetch": "^2.5.12",
"@types/sinon": "^10.0.4",
Expand All @@ -51,7 +51,7 @@
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-deprecation": "^3.0.0",
"jest": "^28.1.0",
"mocha": "8.x",
"mocha": "10.x",
"nodemon": "^3.1.7",
"nyc": "15.1.0",
"prettier": "^3.4.2",
Expand Down
4 changes: 2 additions & 2 deletions ai-sdk/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,14 +40,14 @@
"devDependencies": {
"@temporalio/testing": "^1.18.1",
"@tsconfig/node22": "^22.0.0",
"@types/mocha": "8.x",
"@types/mocha": "10.x",
"@types/node": "^22.9.1",
"@typescript-eslint/eslint-plugin": "^8.18.0",
"@typescript-eslint/parser": "^8.18.0",
"eslint": "^8.57.1",
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-deprecation": "^3.0.0",
"mocha": "8.x",
"mocha": "10.x",
"nodemon": "^3.1.7",
"prettier": "^3.4.2",
"ts-node": "^10.9.2",
Expand Down
4 changes: 2 additions & 2 deletions early-return/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,14 @@
"devDependencies": {
"@temporalio/testing": "^1.18.1",
"@tsconfig/node22": "^22.0.0",
"@types/mocha": "8.x",
"@types/mocha": "10.x",
"@types/node": "^22.9.1",
"@typescript-eslint/eslint-plugin": "^8.18.0",
"@typescript-eslint/parser": "^8.18.0",
"eslint": "^8.57.1",
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-deprecation": "^3.0.0",
"mocha": "8.x",
"mocha": "10.x",
"nodemon": "^3.1.7",
"prettier": "^3.4.2",
"ts-node": "^10.9.2",
Expand Down
4 changes: 2 additions & 2 deletions empty/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,14 +33,14 @@
"devDependencies": {
"@temporalio/testing": "^1.18.1",
"@tsconfig/node22": "^22.0.0",
"@types/mocha": "8.x",
"@types/mocha": "10.x",
"@types/node": "^22.9.1",
"@typescript-eslint/eslint-plugin": "^8.18.0",
"@typescript-eslint/parser": "^8.18.0",
"eslint": "^8.57.1",
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-deprecation": "^3.0.0",
"mocha": "8.x",
"mocha": "10.x",
"nodemon": "^3.1.7",
"prettier": "^3.4.2",
"ts-node": "^10.9.2",
Expand Down
4 changes: 2 additions & 2 deletions hello-world/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,14 +33,14 @@
"devDependencies": {
"@temporalio/testing": "^1.18.1",
"@tsconfig/node22": "^22.0.0",
"@types/mocha": "8.x",
"@types/mocha": "10.x",
"@types/node": "^22.9.1",
"@typescript-eslint/eslint-plugin": "^8.18.0",
"@typescript-eslint/parser": "^8.18.0",
"eslint": "^8.57.1",
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-deprecation": "^3.0.0",
"mocha": "8.x",
"mocha": "10.x",
"nodemon": "^3.1.7",
"prettier": "^3.4.2",
"ts-node": "^10.9.2",
Expand Down
4 changes: 2 additions & 2 deletions message-passing/execute-update/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,14 +32,14 @@
"devDependencies": {
"@temporalio/testing": "^1.18.1",
"@tsconfig/node22": "^22.0.0",
"@types/mocha": "8.x",
"@types/mocha": "10.x",
"@types/node": "^22.9.1",
"@typescript-eslint/eslint-plugin": "^8.18.0",
"@typescript-eslint/parser": "^8.18.0",
"eslint": "^8.57.1",
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-deprecation": "^3.0.0",
"mocha": "8.x",
"mocha": "10.x",
"nodemon": "^3.1.7",
"prettier": "^3.4.2",
"ts-node": "^10.9.2",
Expand Down
4 changes: 2 additions & 2 deletions message-passing/introduction/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,14 @@
"devDependencies": {
"@temporalio/testing": "^1.18.1",
"@tsconfig/node22": "^22.0.0",
"@types/mocha": "8.x",
"@types/mocha": "10.x",
"@types/node": "^22.9.1",
"@typescript-eslint/eslint-plugin": "^8.18.0",
"@typescript-eslint/parser": "^8.18.0",
"eslint": "^8.57.1",
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-deprecation": "^3.0.0",
"mocha": "8.x",
"mocha": "10.x",
"nodemon": "^3.1.7",
"prettier": "^3.4.2",
"ts-node": "^10.9.2",
Expand Down
4 changes: 2 additions & 2 deletions message-passing/safe-message-handlers/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,14 @@
"devDependencies": {
"@temporalio/testing": "^1.18.1",
"@tsconfig/node22": "^22.0.0",
"@types/mocha": "8.x",
"@types/mocha": "10.x",
"@types/node": "^22.9.1",
"@typescript-eslint/eslint-plugin": "^8.18.0",
"@typescript-eslint/parser": "^8.18.0",
"eslint": "^8.57.1",
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-deprecation": "^3.0.0",
"mocha": "8.x",
"mocha": "10.x",
"nodemon": "^3.1.7",
"prettier": "^3.4.2",
"ts-node": "^10.9.2",
Expand Down
2 changes: 1 addition & 1 deletion mutex/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
"eslint": "^8.57.1",
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-deprecation": "^3.0.0",
"mocha": "10.2.0",
"mocha": "10.x",
"nodemon": "^3.1.7",
"prettier": "^3.4.2",
"ts-node": "^10.9.2",
Expand Down
3 changes: 3 additions & 0 deletions nexus-standalone-operations/.eslintignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
node_modules
lib
.eslintrc.js
48 changes: 48 additions & 0 deletions nexus-standalone-operations/.eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
const { builtinModules } = require('module');

const ALLOWED_NODE_BUILTINS = new Set(['assert']);

module.exports = {
root: true,
parser: '@typescript-eslint/parser',
parserOptions: {
project: './tsconfig.json',
tsconfigRootDir: __dirname,
},
plugins: ['@typescript-eslint', 'deprecation'],
extends: [
'eslint:recommended',
'plugin:@typescript-eslint/eslint-recommended',
'plugin:@typescript-eslint/recommended',
'prettier',
],
rules: {
// recommended for safety
'@typescript-eslint/no-floating-promises': 'error', // forgetting to await Activities and Workflow APIs is bad
'deprecation/deprecation': 'warn',

// code style preference
'object-shorthand': ['error', 'always'],

// relaxed rules, for convenience
'@typescript-eslint/no-unused-vars': [
'warn',
{
argsIgnorePattern: '^_',
varsIgnorePattern: '^_',
},
],
'@typescript-eslint/no-explicit-any': 'off',
},
overrides: [
{
files: ['src/workflows.ts', 'src/workflows-*.ts', 'src/workflows/*.ts'],
rules: {
'no-restricted-imports': [
'error',
...builtinModules.filter((m) => !ALLOWED_NODE_BUILTINS.has(m)).flatMap((m) => [m, `node:${m}`]),
],
},
},
],
};
2 changes: 2 additions & 0 deletions nexus-standalone-operations/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
lib
node_modules
1 change: 1 addition & 0 deletions nexus-standalone-operations/.npmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
package-lock=false
1 change: 1 addition & 0 deletions nexus-standalone-operations/.nvmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
22
18 changes: 18 additions & 0 deletions nexus-standalone-operations/.post-create
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
To begin development, install the Temporal CLI:

Mac: {cyan brew install temporal}
Other: Download and extract the latest release from https://github.com/temporalio/cli/releases/latest

Start Temporal Server:

{cyan temporal server start-dev}

Use Node version 18+ (v22.x is recommended):

Mac: {cyan brew install node@22}
Other: https://nodejs.org/en/download/

Then, in the project directory, using two other shells, run these commands:

{cyan npm run start.watch}
{cyan npm run workflow}
1 change: 1 addition & 0 deletions nexus-standalone-operations/.prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
lib
2 changes: 2 additions & 0 deletions nexus-standalone-operations/.prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
printWidth: 120
singleQuote: true
74 changes: 74 additions & 0 deletions nexus-standalone-operations/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
# Nexus Standalone Operations

This sample demonstrates how to execute Nexus Operations directly from client code, without wrapping them in a caller Workflow. It shows both synchronous and workflow-backed Operations, plus listing and counting standalone Nexus Operation executions.

### Temporal Typescript SDK support for Standalone Nexus Operations is at [Pre-release](https://docs.temporal.io/evaluate/development-production-features/release-stages#pre-release).

All APIs are experimental and may be subject to backwards-incompatible changes.

Standalone Nexus operations require a server version that supports this feature. Use the dev server build at https://github.com/temporalio/cli/releases/tag/v1.7.2-standalone-nexus-operations.

## Structure

- `src/api.ts` - Defines the Nexus Service, including its input and output types.
- `src/service/handler.ts` - Implements the synchronous `echo` Operation and the workflow-backed `hello` Operation.
- `src/service/workflows.ts` - Defines the Workflow used by the `hello` Operation.
- `src/service/worker.ts` - Runs the Worker that hosts the Nexus Service handler.
- `src/starter.ts` - Executes standalone Nexus Operations from a Temporal Client.

## Prerequisites

A Temporal dev server with the dynamic config flags required for standalone Nexus operations:

```bash
temporal server start-dev \
--dynamic-config-value "nexusoperation.enableStandalone=true" \
--dynamic-config-value "history.enableChasmCallbacks=true"
```

## Running the sample

1. Install NPM dependencies:

```sh
npm install # or `pnpm` or `yarn`
```

2. Create the Nexus endpoint:

```sh
temporal operator nexus endpoint create \
--name nexus-standalone-operations-endpoint \
--target-namespace default \
--target-task-queue nexus-standalone-operations
```

3. In one shell, start the Worker:

```sh
npm run worker
```

4. In another shell, execute the sample:

```sh
npm run starter
Comment thread
Evanthx marked this conversation as resolved.
```

Example output:

```
Echo result: hello
Echo result from existing operation handle: hello

Started myNexusService.hello. Operation ID: hello-...
myNexusService.hello result: Hello, World!

Listing Nexus operations:
Operation ID: hello-..., Operation: hello, Status: COMPLETED
Operation ID: echo-..., Operation: echo, Status: COMPLETED

Total Nexus operations: 2
```

If you run the starter multiple times, the listing and count will include additional Operations for the endpoint.
51 changes: 51 additions & 0 deletions nexus-standalone-operations/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
{
"name": "nexus-standalone-operations",
"version": "0.1.0",
"private": true,
"scripts": {
"build": "tsc --build",
"build.watch": "tsc --build --watch",
"format": "prettier --write .",
"format:check": "prettier --check .",
"lint": "eslint .",
"worker": "ts-node src/worker/worker.ts",
"worker.watch": "nodemon --watch src src/worker/worker.ts",
"starter": "ts-node src/starter.ts",
"test": "mocha --exit --require ts-node/register --require source-map-support/register src/mocha/*.test.ts"
},
"nodemonConfig": {
"execMap": {
"ts": "ts-node"
},
"ext": "ts",
"watch": [
"src"
]
},
"dependencies": {
"@temporalio/client": "1.18.1",
"@temporalio/envconfig": "1.18.1",
"@temporalio/nexus": "1.18.1",
"@temporalio/worker": "1.18.1",
"@temporalio/workflow": "1.18.1",
"nanoid": "~3.3.12",
"nexus-rpc": "^0.0.2"
},
"devDependencies": {
"@temporalio/testing": "1.18.1",
"@tsconfig/node22": "^22.0.0",
"@types/mocha": "10.x",
"@types/node": "^22.9.1",
"@typescript-eslint/eslint-plugin": "^8.18.0",
"@typescript-eslint/parser": "^8.18.0",
"eslint": "^8.57.1",
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-deprecation": "^3.0.0",
"mocha": "10.x",
"nodemon": "^3.1.7",
"prettier": "^3.4.2",
"source-map-support": "^0.5.21",
"ts-node": "^10.9.2",
"typescript": "^5.6.3"
}
}
22 changes: 22 additions & 0 deletions nexus-standalone-operations/src/api.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import * as nexus from 'nexus-rpc';

export const myNexusService = nexus.service('myNexusService', {
echo: nexus.operation<EchoInput, EchoOutput>(),
hello: nexus.operation<HelloInput, HelloOutput>(),
});

export interface EchoInput {
message: string;
}

export interface EchoOutput {
message: string;
}

export interface HelloInput {
name: string;
}

export interface HelloOutput {
greeting: string;
}
Loading