# SpreadJS Collaborative Document Auto Read/Write Demo

This demo shows how to programmatically read and modify SpreadJS collaborative documents using a server-side Bot, enabling automatic data updates without manual intervention.

## Overview

This demo simulates a **Weather Query Bot** scenario:

1. Users open a collaborative spreadsheet in the browser and fill in city names in column A
2. A server-side Bot automatically reads the city list from the document every 5 seconds
3. The Bot queries a weather service for each city's weather data
4. The Bot writes the results (temperature, feels like, time) back to columns B, C, D of the collaborative document
5. The browser displays the updated data in real time

Throughout this process, the Bot and browser users share the same collaborative document. Changes made by the Bot are pushed to all connected clients in real time.

## Project Structure

```
spread-collaboration-demo/
├── public/                      # Frontend static assets
│   ├── index.html               # Page entry point
│   ├── client.js                # Frontend collaboration client (source)
│   └── client.bundle.js         # Webpack-bundled client code
├── src/                         # Backend code
│   ├── server.js                # Entry point: starts HTTP server, collaboration server, and Bot
│   ├── node-env.js              # Node.js environment shim (enables SpreadJS to run in Node)
│   ├── license-key.js           # SpreadJS license key  
│   ├── bot-reader.js            # Bot reader: reads city list from collaborative document
│   ├── bot-writer.js            # Bot writer: writes weather data to collaborative document
│   └── weather-service.js       # Weather service: simulates weather queries
├── docs.db                      # SQLite database storing collaborative document data
├── package.json                 # Project dependencies
└── webpack.config.js            # Webpack bundling configuration
```

## Core Concepts

### 1. How the Bot Reads Collaborative Documents

The core read flow (see `src/bot-reader.js`):

```
documentServices.fetch(docId)  →  Fetch document snapshot
                ↓
workbook.collaboration.fromSnapshot(data)  →  Load snapshot into a temporary Workbook
                ↓
sheet.getValue(row, col)  →  Read cell data
                ↓
workbook.destroy()  →  Destroy temporary Workbook to free resources
```

Key point: The Bot fetches the latest document snapshot via `documentServices.fetch()`, then loads the snapshot data into a SpreadJS Workbook object to read cell values just like working with a regular spreadsheet.

### 2. How the Bot Writes to Collaborative Documents

The core write flow (see `src/bot-writer.js`):

```
documentServices.fetch(docId)  →  Fetch latest document snapshot
                ↓
workbook.collaboration.fromSnapshot(data)  →  Load snapshot into a temporary Workbook
                ↓
workbook.collaboration.onChangeSet(callback)  →  Register listener to capture ops
                ↓
workbook.collaboration.startBatchOp()  →  Begin batch operation
sheet.setValue(row, col, value)           →  Set cell values (generates ops)
workbook.collaboration.endBatchOp()      →  End batch operation
                ↓
documentServices.submit(docId, op)  →  Submit ops to the collaboration server
                ↓
Server processes concurrent ops via OT algorithm → Broadcasts to all clients
```

Key points:
- The Bot does not modify the document directly. Instead, it **generates ops and submits them** to participate in collaboration
- The `onChangeSet` callback captures operation instructions generated by `setValue`
- `documentServices.submit()` submits ops to the collaboration server, which handles OT transformation and broadcasting
- This ensures the Bot's changes follow the same collaboration rules as manual edits, avoiding conflicts

### 3. Node.js Environment Shim

SpreadJS is originally a browser-side component. Running it in Node.js requires simulating the DOM environment (see `src/node-env.js`):
- `jsdom` simulates `window`, `document`, and other browser globals
- `canvas` module simulates the `<canvas>` element
- `filereader` module provides the `FileReader` API

## Getting Started

### Configure License Key

Running SpreadJS in Node.js requires a special license key; please configure it in the src/license-key file.

```js
// src/license-key.js
export const licenseKey = 'YOUR_SPREADJS_LICENSE_KEY';
```

You can obtain a license key from [https://www.grapecity.com/spreadjs](https://www.grapecity.com/spreadjs).

### Install Dependencies

```bash
npm install
```

### Build Frontend Code

```bash
npm run build
```

### Start the Server

```bash
npm start
```

Once the server starts, visit `http://127.0.0.1:8080/index.html` in your browser.

## Usage

1. Open the page in your browser. The spreadsheet will auto-initialize with 5 sample cities (New York, Los Angeles, etc.)
2. The server-side Bot reads city names from column A every 5 seconds, queries weather data, and writes results to columns B-D
3. You can manually add new city names in column A (must be a city defined in `weather-service.js`). The Bot will automatically query and fill in weather data
4. Open multiple browser windows to the same URL to observe real-time collaborative synchronization

## Supported Cities

New York, Los Angeles, Chicago, Houston, Phoenix, Philadelphia, San Antonio, San Diego, Dallas, San Francisco, Seattle, Denver, Boston, Miami, Atlanta, Las Vegas, Portland, Detroit, Minneapolis, Honolulu
