Skip to content

Commit

Permalink
Update examples/with-temporal (#33674)
Browse files Browse the repository at this point in the history
Update `with-temporal` example to latest version of Temporal TS SDK API.

AFAICT, next.js doesn't yet support `type: "module"` in root `package.json`, so I added a nested `package.json` for Temporal.

## Documentation / Examples

- [x] Make sure the linting passes by running `yarn lint`


Co-authored-by: Balázs Orbán <18369201+balazsorban44@users.noreply.github.com>
  • Loading branch information
lorensr and balazsorban44 committed Sep 30, 2022
1 parent 1545af5 commit 05c2fe0
Show file tree
Hide file tree
Showing 15 changed files with 111 additions and 180 deletions.
28 changes: 22 additions & 6 deletions examples/with-temporal/package.json
Expand Up @@ -5,23 +5,39 @@
"build": "next build",
"start": "next start",
"type-check": "tsc",
"build-worker": "tsc --build temporal/src/worker/tsconfig.json",
"build-worker.watch": "tsc --build --watch temporal/src/worker/tsconfig.json",
"start-worker": "nodemon -w temporal/lib/ -x 'node temporal/lib/worker || (sleep 5; touch temporal/lib/worker/index.js)'"
"build:worker": "tsc --build temporal/tsconfig.json",
"build:worker.watch": "tsc --build --watch temporal/tsconfig.json",
"start:worker": "cross-env TS_NODE_PROJECT=\"temporal/tsconfig.json\" node --loader ts-node/esm temporal/src/worker.ts",
"start:worker.watch": "cross-env TS_NODE_PROJECT=\"temporal/tsconfig.json\" nodemon temporal/src/worker.ts"
},
"dependencies": {
"next": "latest",
"node-fetch": "^3.0.0",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"temporalio": "^0.3.0"
"temporalio": "^0.17.2"
},
"devDependencies": {
"@babel/core": "^7.15.0",
"@tsconfig/node14": "^1.0.0",
"@tsconfig/node16": "^1.0.0",
"@types/node": "^12.12.21",
"@types/node-fetch": "^3.0.3",
"@types/react": "^17.0.2",
"@types/react-dom": "^17.0.1",
"@typescript-eslint/eslint-plugin": "^5.3.0",
"@typescript-eslint/parser": "^5.3.0",
"cross-env": "^7.0.3",
"nodemon": "^2.0.12",
"typescript": "^4.3.5"
"ts-node": "^10.2.1",
"typescript": "^4.4.2"
},
"nodemonConfig": {
"execMap": {
"ts": "node --loader ts-node/esm"
},
"ext": "ts",
"watch": [
"temporal/src"
]
}
}
17 changes: 10 additions & 7 deletions examples/with-temporal/pages/api/orders/index.ts
@@ -1,6 +1,6 @@
import { NextApiRequest, NextApiResponse } from 'next'
import { Connection, WorkflowClient } from '@temporalio/client'
import { Order } from '../../../temporal/src/interfaces/workflows'
import { WorkflowClient } from '@temporalio/client'
import { order } from '../../../temporal/src/workflows'

export type Data = {
result: string
Expand All @@ -25,11 +25,14 @@ export default async function handler(
const { itemId, quantity } = JSON.parse(req.body)

// Connect to our Temporal Server running locally in Docker
const connection = new Connection()
const client = new WorkflowClient(connection.service)
const example = client.stub<Order>('order', { taskQueue: 'orders' })
const client = new WorkflowClient()

// Execute the order Workflow and wait for it to finish
const result = await client.execute(order, {
taskQueue: 'my-nextjs-project',
workflowId: 'my-business-id',
args: [userId, itemId, quantity],
})

// Execute the Order workflow and wait for it to finish
const result = await example.execute(userId, itemId, quantity)
return res.status(200).json({ result })
}
3 changes: 3 additions & 0 deletions examples/with-temporal/temporal/package.json
@@ -0,0 +1,3 @@
{
"type": "module"
}
@@ -1,3 +1,28 @@
import fetch from 'node-fetch'

export type ChargeResult = {
status: string
errorMessage?: string
}

export async function chargeUser(
userId: string,
itemId: string,
quantity: number
): Promise<ChargeResult> {
// TODO send request to the payments service that looks up the user's saved
// payment info and the cost of the item and attempts to charge their payment
// method.
console.log(`Charging user ${userId} for ${quantity} of item ${itemId}`)
try {
const response = await fetch('http://httpbin.org/get?status=success')
const body: any = await response.json()
return { status: body.args.status }
} catch (e: any) {
return { status: 'failure', errorMessage: e.message }
}
}

export async function checkAndDecrementInventory(
itemId: string,
quantity: number
Expand All @@ -24,5 +49,6 @@ export async function incrementInventory(
// { $inc: { numAvailable: quantity } }
// )
// return result.modifiedCount === 1
console.log(`Incrementing ${itemId} inventory by ${quantity}`)
return true
}
17 changes: 0 additions & 17 deletions examples/with-temporal/temporal/src/activities/payment.ts

This file was deleted.

21 changes: 0 additions & 21 deletions examples/with-temporal/temporal/src/activities/tsconfig.json

This file was deleted.

16 changes: 0 additions & 16 deletions examples/with-temporal/temporal/src/interfaces/tsconfig.json

This file was deleted.

5 changes: 0 additions & 5 deletions examples/with-temporal/temporal/src/interfaces/workflows.ts

This file was deleted.

18 changes: 18 additions & 0 deletions examples/with-temporal/temporal/src/worker.ts
@@ -0,0 +1,18 @@
import { Worker } from '@temporalio/worker'
import { URL } from 'url'
import path from 'path'
import * as activities from './activities.js'

// Support running both complied code and ts-node/esm loader
const workflowsPath = new URL(
`./workflows${path.extname(import.meta.url)}`,
import.meta.url
).pathname

const worker = await Worker.create({
workflowsPath,
activities,
taskQueue: 'my-nextjs-project',
})

await worker.run()
18 changes: 0 additions & 18 deletions examples/with-temporal/temporal/src/worker/index.ts

This file was deleted.

27 changes: 0 additions & 27 deletions examples/with-temporal/temporal/src/worker/tsconfig.json

This file was deleted.

@@ -1,11 +1,13 @@
import { Order } from '../interfaces/workflows'
import {
checkAndDecrementInventory,
incrementInventory,
} from '@activities/inventory'
import { chargeUser, ChargeResult } from '@activities/payment'
import { proxyActivities } from '@temporalio/workflow'
// Only import the activity types
import type * as activities from './activities.js'

async function main(
const { chargeUser, checkAndDecrementInventory, incrementInventory } =
proxyActivities<typeof activities>({
startToCloseTimeout: '1 minute',
})

export async function order(
userId: string,
itemId: string,
quantity: number
Expand All @@ -15,8 +17,12 @@ async function main(
quantity
)
if (haveEnoughInventory) {
const result: ChargeResult = await chargeUser(userId, itemId, quantity)
if (result.success) {
const result: activities.ChargeResult = await chargeUser(
userId,
itemId,
quantity
)
if (result.status === 'success') {
return `Order successful!`
} else {
await incrementInventory(itemId, quantity)
Expand All @@ -26,5 +32,3 @@ async function main(
return `Sorry, we don't have enough items in stock to fulfill your order.`
}
}

export const workflow: Order = { main }
46 changes: 0 additions & 46 deletions examples/with-temporal/temporal/src/workflows/tsconfig.json

This file was deleted.

15 changes: 15 additions & 0 deletions examples/with-temporal/temporal/tsconfig.json
@@ -0,0 +1,15 @@
{
"extends": "@tsconfig/node16/tsconfig.json",
"version": "4.4.2",
"compilerOptions": {
"target": "es2017",
"module": "esnext",
"moduleResolution": "node",
"declaration": true,
"declarationMap": true,
"sourceMap": true,
"rootDir": "./src",
"outDir": "./lib"
},
"include": ["src/**/*.ts"]
}
8 changes: 2 additions & 6 deletions examples/with-temporal/tsconfig.json
Expand Up @@ -12,12 +12,8 @@
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"jsx": "preserve",
"paths": {
"@activities": ["./temporal/src/activities"],
"@activities/*": ["./temporal/src/activities/*"]
}
"jsx": "preserve"
},
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"],
"exclude": ["node_modules"]
"exclude": ["temporal/"]
}

0 comments on commit 05c2fe0

Please sign in to comment.