# Entity pattern

> For the complete documentation index, see [llms.txt](https://docs.temporal.io/llms.txt).
> Any documentation page is available as raw Markdown by appending `.md` to its URL.
> For related questions, query https://docs.temporal.io/api/retrieve?q=<question>&jtb=<job-to-be-done>&src=md-page&agent=<your-name> (no auth; returns JSON `{content, source_url, page_url}`, with `source_url` pointing to Markdown for docs pages). Don't include personal data or credentials.

> Implement the Single-Entity Design Pattern in TypeScript to manage Workflow iterations and handle Signals, ensuring efficient Workflow Execution with updates.

### Single-entity design pattern in TypeScript 

The following is a simple pattern that represents a single entity.
It tracks the number of iterations regardless of frequency, and calls `continueAsNew` while properly handling pending updates from Signals.

<!--SNIPSTART typescript-entity-pattern-workflow-->
[typescript-sandbox/src/best-practices/entity-pattern/workflows.ts](https://github.com/temporalio/documentation-sdk-code-examples/blob/main/typescript-sandbox/src/best-practices/entity-pattern/workflows.ts)
```ts
interface Input {
  /* Define your Workflow input type here */
  entityId: string;
}
interface Update {
  /* Define your Workflow update type here */
  value: number;
}

export const updateSignal = defineSignal<[Update]>('update');

const MAX_ITERATIONS = 1;

export async function entityWorkflow(input: Input, isNew = true): Promise<void> {
  try {
    const pendingUpdates = Array<Update>();
    setHandler(updateSignal, (updateCommand) => {
      pendingUpdates.push(updateCommand);
    });

    if (isNew) {
      await setup(input);
    }

    for (let iteration = 1; iteration <= MAX_ITERATIONS; ++iteration) {
      // Ensure that we don't block the Workflow Execution forever waiting
      // for updates, which means that it will eventually Continue-As-New
      // even if it does not receive updates.
      await condition(() => pendingUpdates.length > 0, '1 day');

      while (pendingUpdates.length) {
        const update = pendingUpdates.shift()!;
        await runAnActivityOrChildWorkflow(update);
      }
    }
  } catch (err) {
    if (isCancellation(err)) {
      await CancellationScope.nonCancellable(async () => {
        await cleanup();
      });
    }
    throw err;
  }
  await continueAsNew<typeof entityWorkflow>(input, false);
}
```
<!--SNIPEND-->
