# Server-side Spreadsheet

Use `Spreadsheet` from `libs/spreadsheet-state/interface/spreadsheet-interface.ts` when you want to apply spreadsheet operations on the server (API routes, workers, job processors), then evaluate formulas before persisting or broadcasting changes.

## Import

Use the server entrypoint:

```ts
import { Spreadsheet } from "@rowsncolumns/spreadsheet-state/server";
```

## 1) Initialize state

```ts
import type { CellData, Sheet, TableView } from "@rowsncolumns/spreadsheet";
import type { SheetData } from "@rowsncolumns/spreadsheet-state";
import { Spreadsheet } from "@rowsncolumns/spreadsheet-state/server";

const spreadsheet = new Spreadsheet();

const sheets: Sheet[] = [
  { sheetId: 1, rowCount: 200, columnCount: 26, title: "Sheet1" },
];
const sheetData: SheetData<CellData> = { 1: [] };
const tables: TableView[] = [];

spreadsheet.sheets = sheets;
spreadsheet.sheetData = sheetData;
spreadsheet.tables = tables;
```

## 2) Apply updates

Use `changeBatch` for cell values/formulas (single or multi-range):

```ts
spreadsheet.changeBatch(
  1,
  {
    startRowIndex: 1,
    endRowIndex: 1,
    startColumnIndex: 1,
    endColumnIndex: 1,
  },
  [[10]],
);

spreadsheet.changeBatch(
  1,
  {
    startRowIndex: 1,
    endRowIndex: 1,
    startColumnIndex: 2,
    endColumnIndex: 2,
  },
  [["=A1*2"]],
);
```

You can also use structural APIs like `insertRow`, `insertColumn`, `deleteRow`, `deleteColumn`, `changeFormatting`, `updateTable`, etc. on the same `Spreadsheet` instance.

## 3) Run evaluation

After backend edits, explicitly flush calculations:

```ts
const results = await spreadsheet.calculatePending();
```

Useful variants:

* `await spreadsheet.calculatePending()`: Runs only queued operations and returns calculated result entries.
* `await spreadsheet.flushCalculations()`: Runs queued operations but does not return result entries.
* `await spreadsheet.calculateAll()`: Scans current `sheetData` formulas and evaluates them.

If you replace `sheetData` directly (outside `changeBatch`), call `calculateAll()` for a full formula pass, or call `rebuildGraph()` and enqueue explicit operations before `calculatePending()`.

## 4) Read updated values

`calculatePending`/`flushCalculations`/`calculateAll` apply results back into `spreadsheet.sheetData` via the internal calculation pipeline.

```ts
const cellB1 = spreadsheet.sheetData[1]?.[1]?.values?.[2];
```

## 5) Persist or broadcast patches

Every mutation pushes history patches that you can forward to persistence/collab layers.

```ts
const patchTuples = spreadsheet.getPatchTuples(); // for undo/redo style patch consumers
const fullStatePatches = await spreadsheet.generateStatePatches(); // full-state patch export
spreadsheet.clearPatches(); // optional reset after persisting/broadcasting
```

## Worker configuration (recommended)

For backend runtimes, provide a calculation worker explicitly:

```ts
import { Worker } from "node:worker_threads";
import { Spreadsheet } from "@rowsncolumns/spreadsheet-state/server";

const spreadsheet = new Spreadsheet({
  createCalculationWorker: () =>
    new Worker(require.resolve("@rowsncolumns/calculation-worker/worker")),
});
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.rowsncolumns.app/configuration/spreadsheet-interface.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
