Temporal-time-utils - This is a library with some reusable functions for Temporal.io TypeScript SDK

Overview

temporal-time-utils

This is a library with some reusable functions for Temporal.io TypeScript SDK:

  • sleepUntil: sleep to a specific date, instead of by num of milliseconds
  • UpdatableTimer: sleep to a specific date, updatable and queryable
  • ScheduleWorkflow: schedule other workflows by extended cron syntax, with support for jitter, timezone, max invocations, manual triggers, pausing/unpausing, querying future executions, and more.

This serves as both a utility library and a demonstration of how you can publish reusable Temporal libraries (both for Workflows and Activities).

npm i temporal-time-utils

Repo: https://github.com/sw-yx/temporal-time-utils

sleepUntil

This is a simple drop in replacement for Temporal's workflow.sleep() API for when you need to sleep to a specific date rather than a fixed number of milliseconds.

import { sleepUntil } from "temporal-time-utils";

// inside workflow function
sleepUntil("30 Sep " + (new Date().getFullYear() + 1)); // wake up when September ends
sleepUntil("5 Nov 2022 00:12:34 GMT"); // wake up at specific time and timezone

// optional 2nd arg
sleepUntil("5 Nov 2022 00:12:34 GMT", specificDateTime); // take control over the "start" time in case you need to

This is a very simple function - under the hood it just uses date-fns/differenceInMilliseconds to calculate time difference.

This is discussed in the docs https://docs.temporal.io/docs/typescript/workflows#sleep

UpdatableTimer

sleep only lets you set a fixed time upfront. UpdatableTimer is a special class that lets you update that while sleeping. You can consider it the next step up from sleepUntil.

After you instantiate it with an initial datetime to wake up at, it exposes only two APIs: then() for you to await, and .deadline that you can set and get.

// example usage inside workflow function
export async function countdownWorkflow(initialDeadline: Date): Promise<void> {
  const timer = new UpdatableTimer(initialDeadline);
  wf.setHandler(
    setDeadlineSignal,
    (deadline) => void (timer.deadline = deadline)
  ); // send in new deadlines via Signal
  wf.setHandler(timeLeftQuery, () => timer.deadline - Date.now()); // get time left via Query
  await timer; // if you send in a signal with a new time, this timer will resolve earlier!
  console.log("countdown done!");
}

This is discussed in the docs https://docs.temporal.io/docs/typescript/workflows#async-design-patterns.

ScheduleWorkflow

A Workflow that schedules other Workflows.

This is a premade Workflow that you can register in a Worker and call from a client, to invoke other Workflows on a schedule. You can consider this the next step up from "Cron Workflows".

See example usage inside of /apps/fixture:

// inside client file
async function run() {
  const client = new WorkflowClient();
  const handle = await client.start(ScheduleWorkflow, {
    args: [
      exampleWorkflow, // workflow to be executed on a schedule. can be string name.
      {
        args: ["Example arg payload"], // static for now, but possible to modify to make dynamic in future - ask swyx
        // // regular workflow options apply here, with two additions (defaults shown):
        // cancellationType: ChildWorkflowCancellationType.WAIT_CANCELLATION_COMPLETED,
        // parentClosePolicy: ParentClosePolicy.PARENT_CLOSE_POLICY_TERMINATE
      },
      {
        // args
        cronParser: {
          expression: "* * * * *", // every minute
          // options: https://www.npmjs.com/package/cron-parser#user-content-options
        },
        // maxInvocations?: number;
        // jitterMs?: number;
      },
    ],
    taskQueue: "tutorial",
    workflowId: "my-schedule-id",
  });
}

This uses https://www.npmjs.com/package/cron-parser under the hood, thereby getting support for things like timezones and "last of the week" extensions to the cron syntax:

// client.ts
const handle = await client.start(ScheduleWorkflow, {
  args: [
    exampleWorkflow, // as above
    {}, // if no args needed
    {
      // scheduleOptions
      cronParser: {
        expression: "0 0 * * * 1,3L", // run every Monday as well as the last Wednesday of the month
        options: {
          currentDate: "2016-03-27 00:00:01",
          endDate: new Date("Wed, 26 Dec 2012 14:40:00 UTC"),
          tz: "Europe/Athens",
        },
      },
      maxInvocations: 500,
      jitterMs: 1000,
    },
  ],
  taskQueue: "scheduler",
  workflowId: "schedule-for-" + userId,
});

The Workflow exposes a number of useful queries and signals:

import {
  numInvocationsQuery,
  futureScheduleQuery,
  manualTriggerSignal,
  ScheduleWorkflowState,
  stateSignal,
  stateQuery,
  // ...
} from "temporal-time-utils";

await handle.query(numInvocationsQuery); // get how many times exampleWorkflow has been invoked by ScheduleWorkflow
await handle.query(futureScheduleQuery, 3); // get the next 3 times it is set to be invoked. defaults to 5
await handle.signal(manualTriggerSignal); // manually trigger workflow
await handle.signal(stateSignal, "PAUSED" as ScheduleWorkflowState); // pause workflow
await handle.signal(stateSignal, "RUNNING" as ScheduleWorkflowState); // resume workflow
await handle.cancel(); // stop schedule workflow completely
await handle.query(stateQuery); // get wf state (running, paused, or stopped)

This is a decoupled and slightly modified variant of what was discussed in the docs: https://docs.temporal.io/docs/typescript/workflows#schedule-workflow-example

Monorepo details

This project is bootstrapped with https://turborepo.org/.

Build

To build all apps and packages, run the following command:

cd my-turborepo
npm run build

Develop

To develop all apps and packages, run the following command:

cd my-turborepo
npm run dev

Remote Caching

Turborepo can use a technique known as Remote Caching (Beta) to share cache artifacts across machines, enabling you to share build caches with your team and CI/CD pipelines.

cd my-turborepo
npx turbo login
npx turbo link
You might also like...

Dm-utils - Utility classes for ioBroker adapters to support ioBroker.dm

dm-utils Utility classes for ioBroker adapters to support ioBroker.dm. How to use In your ioBroker adapter, add a subclass of DeviceManagement and ove

Jan 2, 2022

DevArms - a collection of developer utils that gives you extra arms to reach more in your tasks

DevArms - a collection of developer utils that gives you extra arms to reach more in your tasks

DevArms is a collection of developer utils that gives you extra arms to reach more in your tasks. It runs completely offline, and cross-platform across Windows, Mac and Linux. Written in Rust, React. Powered by Tauri.

Dec 18, 2022

SUID is all a set of utils and components ported from MUI Core and much more.

Solid.js User Interface Design (SUID) A port of Material-UI (MUI) built with Solid.js SUID is all a set of utils and components ported from MUI Core a

Jan 1, 2023

Simple utils to pack arrays, objects and strings to a flat object (and back again).

packrup Simple utils to pack (and unpack) arrays and strings to a flat object. Status: In Development Please report any issues 🐛 Made possible by my

Dec 23, 2022

The repository shows the compiler (simulator) of the Little Man Computer, which also contains some programs in the LMC programming language for implementing different functions.

Little Man Computer The repository shows the compiler (simulator) of the Little Man Computer, which also contains some programs in the LMC programming

Nov 17, 2022

A simple react project that contain a single page application (SPA) And a simple caculator to make some calculation and there is a section you can see some Math quotes. Ⓜ💯

A simple react project that contain a single page application (SPA) And a simple caculator to make some calculation and there is a section you can see some Math quotes. Ⓜ💯

May 31, 2022

This Repo Contains projects that demonstrate some concepts / algorithms / implemetation in some form of digital visualisation

This Repo Contains projects that demonstrate some concepts / algorithms / implemetation in some form of digital visualisation

Hacktoberfest 2022 OPEN FIRST Pull Request - GET STARTED WITH OPENSOURCE AND WIN SOME AWWSOME SWAGS 🎉 Contributors of Hacktoberfest 2022 This project

Nov 7, 2022

Lightweight reusable Web3 UI components for dapps.

Lightweight reusable Web3 UI components for dapps.

Web3UIKit 🧙‍♂️ Beautiful and lightweight UI components for web3 developers. This UI library will speed up your dapp development no matter which chain

Dec 26, 2022

Convert some JavaScript/TypeScript code string into a .d.ts TypeScript Declaration code string

convert-to-dts Converts the source code for any .js or .ts file into the equivalent .d.ts code TypeScript would generate. Usage import { convertToDecl

Mar 3, 2022
Comments
  • package does not seem to work with ts-node in samples-typescript

    package does not seem to work with ts-node in samples-typescript

    Thanks for making this package!

    I've installed and imported temporal-time-utils in an example from temporal samples-typescript but when I try to run my workflow:

    $ npm run workflow
    
    > [email protected] workflow
    > ts-node src/client.ts
    
    samples-typescript/hello-world/node_modules/temporal-time-utils/index.ts:1
    export { UpdatableTimer } from "./UpdatableTimer";
    ^^^^^^
    SyntaxError: Unexpected token 'export'
        at Object.compileFunction (node:vm:352:18)
        at wrapSafe (node:internal/modules/cjs/loader:1033:15)
        at Module._compile (node:internal/modules/cjs/loader:1069:27)
        at Module._extensions..js (node:internal/modules/cjs/loader:1159:10)
        at Object.require.extensions.<computed> [as .ts] (samples-typescript/hello-world/node_modules/ts-node/src/index.ts:1587:43)
        at Module.load (node:internal/modules/cjs/loader:981:32)
        at Function.Module._load (node:internal/modules/cjs/loader:827:12)
        at Module.require (node:internal/modules/cjs/loader:1005:19)
        at require (node:internal/modules/cjs/helpers:102:18)
        at Object.<anonymous> (samples-typescript/hello-world/src/workflows.ts:4:1)
    

    I'm guessing it was published without the build output.

    opened by devdoshi 0
  • Create type safe way to pass workflow arguments to `ScheduleWorkflow`

    Create type safe way to pass workflow arguments to `ScheduleWorkflow`

    Current example in README is both type unsafe and doesn't work because functions are not JSON serializable, this helper addresses the issue and adds type-safety:

    Schedule.args = <W extends Workflow>(
      workflow: W | string, opts: ScheduleWorkflowOptions<W>
    ): [string, ScheduleWorkflowOptions<W>] {
        return [typeof workflow === 'string' ? workflow : workflow.name, args];
    }
    
    client.execute(Schedule, { args: Schedule.args(myWorkflow3, { args: [1, 2] }) })
    

    Also this type uses the child workflow options which aren't the same as the client's workflow options, you might want to fix that while you're at it https://github.com/sw-yx/temporal-time-utils/blob/d2f6d7aebcc6c537c518e49abadd1245ce4b126d/packages/temporal-time-utils/ScheduleWorkflow.ts#L30

    opened by bergundy 5
Grupprojekt för kurserna 'Javascript med Ramverk' och 'Agil Utveckling'

JavaScript-med-Ramverk-Laboration-3 Grupprojektet för kurserna Javascript med Ramverk och Agil Utveckling. Utvecklingsguide För information om hur utv

Svante Jonsson IT-Högskolan 3 May 18, 2022
Hemsida för personer i Sverige som kan och vill erbjuda boende till människor på flykt

Getting Started with Create React App This project was bootstrapped with Create React App. Available Scripts In the project directory, you can run: np

null 4 May 3, 2022
Kurs-repo för kursen Webbserver och Databaser

Webbserver och databaser This repository is meant for CME students to access exercises and codealongs that happen throughout the course. I hope you wi

null 14 Jan 3, 2023
parses human-readable strings for JavaScript's Temporal API

?? temporal-parse What is the temporal-parse? Temporal is the next generation of JavaScript's standard Date API. It's currently proposed to TC39 (see:

Eser Ozvataf 22 Jan 2, 2023
The iofod SDK provides developers with the ability to interact with the main iofod interface within the Web worker, enabling rapid development of iofod extensions through the SDK.

iofod-sdk English | 简体中文 The iofod SDK provides developers with the ability to interact with the main iofod interface within the Web worker, enabling

iofod, Inc. 47 Oct 17, 2022
Functions Recipes is a library of examples to help you getting started with Salesforce Functions and get used to their main features.

Functions Recipes Introduction Salesforce Functions lets you use the Salesforce Platform for building event-driven, elastically scalable apps and expe

Trailhead Apps 172 Dec 29, 2022
A JavaScript Library for things I use often, as well as some helper functions

Elements A JavaScript Library for things I use often, as well as some helper functions. Full documentation below. Inspired by Habitat, another library

Magnogen 3 Apr 21, 2022
CandyPay SDK lets you effortlessly create NFT minting functions for Candy Machine v2 collections.

@candypay/sdk CandyPay SDK lets you effortlessly create NFT minting functions for Candy Machine v2 collections. Simulate minting transactions for mult

Candy Pay 33 Nov 16, 2022
This is a demo project for the SecTester JS SDK framework, with some installation and usage examples

SecTester SDK Demo Table of contents About this project About SecTester Setup Fork and clone this repo Get a Bright API key Explore the demo applicati

NeuraLegion 15 Dec 16, 2022