# Snippets: variables, storage and long runs

> Oktul Code Studio script snippets for script variables, stored values and runs that continue themselves, copied from the console and run by its tests.
>
> Documentation for Oktul Code Studio, for Jira Cloud and Confluence Cloud, by Oktul: https://oktul.com/docs/plugins/code-studio/snippets/variables-storage-and-long-runs/

These are the snippets the console's **Snippets** dialog offers under Variables, storage and long runs. Each is TypeScript; in a `.js` script the console shows the same code with its types removed. Every one runs unchanged in Code Studio's own tests. How the API they call behaves is in [writing scripts](../../writing-scripts/) and the [script API reference](../../script-api/).

## Read script variables

Script variables are set in the console's Variables section. A secret one reaches the script and is blanked out of every log line and result.

```ts
export default async function (event: unknown, context: ScriptContext) {
    const { SPACE_KEY, API_TOKEN } = context.environment.vars;
    if (!SPACE_KEY) throw new Error('Set the SPACE_KEY script variable.');
    log.info(`Working in ${SPACE_KEY}, token set: ${Boolean(API_TOKEN)}`);
    return { space: SPACE_KEY, mode: context.mode };
}
```

## Remember something between runs

Keeps JSON between runs, here to act on each work item once. A time to live clears the key by itself.

```ts
export default async function (event: { issue?: { key: string } } | null) {
    const key = event?.issue?.key ?? 'DEMO-1';
    const seen = await store.get<boolean>(`welcomed:${key}`);
    if (seen) return { key, skipped: true };

    log.info(`First time for ${key}`);
    await store.set(`welcomed:${key}`, true, { ttlSeconds: 30 * 24 * 60 * 60 });
    return { key, skipped: false };
}
```

## A long loop that resumes

Works through a list and marks its place with context.checkpoint. When the run continues in a new invocation, it starts from the last checkpoint instead of the top.

```ts
interface State {
    next: number;
}

export default async function (event: unknown, context: ScriptContext<State>) {
    const keys = Array.from({ length: 500 }, (_, i) => `DEMO-${i + 1}`);
    let done = 0;
    for (let i = context.resumedFrom?.next ?? 0; i < keys.length; i++) {
        await jira.put(`/rest/api/3/issue/${keys[i]}`, { fields: { labels: ['migrated'] } }, { query: { notifyUsers: false } });
        done++;
        if (i % 25 === 24) context.checkpoint({ next: i + 1 });
    }
    return { done };
}
```

## Related

- [Writing scripts](../../writing-scripts/)
- [Requests to other systems](../../requests-to-other-systems/)
- [Script examples](../../script-examples/)

---

A problem or a question? Write to [support@oktul.com](mailto:support@oktul.com) or open a request in the [Help Center](https://oktul.atlassian.net/servicedesk/customer/portals). Both reach the same service desk, so either way the request gets a reference and an SLA measuring the response.
