# Example

## Main (`index.js`)

{% code lineNumbers="true" %}

```javascript
const { Window, ipc, app } = require('positron.js');
const { Menu, MenuItem } = require('positron.js/menu');
const fs = require('fs');
const path = require('path');

// 1. Initialize the Native Window Configuration
const mainWindow = new Window({
  width: 1000,
  height: 600,
  darwinOptions: {
    titlebarVisible: true,
    minimizable: false, // Disables the yellow minimize button on macOS
  }
});

const htmlFilePath = path.join(__dirname, 'index.html');
const dataFilePath = path.join(__dirname, 'data.txt');
const screenshotPath = path.join(__dirname, 'captured_page.png');

// 2. Window Lifecycle Management ("ready" event)
mainWindow.on('ready', () => {
  console.log('IPC Socket connection established. Window is ready for commands.');

  // Set initial window properties & content
  mainWindow.setTitle("Positron Demo");
  mainWindow.loadFile(htmlFilePath);
  mainWindow.openDevTools();

  // Construct and assign a Native Application Menu
  const appMenu = new Menu().addItem(
    new MenuItem({
      label: 'File',
      items: [
        new MenuItem({ label: 'New', channel: 'menu:new', payload: '{}', key: 'n' }),
        new MenuItem({ label: 'Open', channel: 'menu:open', payload: '{}' }),
        new MenuItem({ separator: true }),
        new MenuItem({ label: 'Save', channel: 'menu:save', payload: '{}' })
      ]
    })
  );
  mainWindow.setMenu(appMenu);

  // Outbound IPC: Push a message to the client-side renderer
  mainWindow.sendIpc('hello-world', { message: 'Hello from the main process!' });

  // Outbound Command Action: Test dynamic property updates after 3 seconds
  setTimeout(() => {
    mainWindow.setTitle("Updated Window Title");
  }, 3000);
});

// 3. Window State & Navigation Events
mainWindow.on('navigated', (targetPath) => {
  console.log(`Window navigated to: ${targetPath}`);
  // Automate a screenshot every time the window layout finishes loading a page
  mainWindow.capturePage();
});

mainWindow.on('title-updated', (newTitle) => {
  console.log(`Title track event fired. New title is: "${newTitle}"`);
});

// 4. Client-to-Main IPC Routing Handlers
ipc.handle('hello-world', (data) => {
  // Forward incoming client UI events back into custom layout toast commands
  mainWindow.sendCommand('toast:show', data.message);
});

ipc.handle('alert-file-data', () => {
  try {
    const data = fs.readFileSync(dataFilePath, 'utf-8');
    mainWindow.alert(data);
  } catch (err) {
    console.error("Failed to read system file for alert dialog:", err);
  }
});

// 5. Global Application Events (app.events)
app.events.on('menu-action', (data) => {
  console.log(`Menu Item Clicked! Channel: ${data.channel} | Payload: ${JSON.stringify(data.payload)}`);
});

app.events.on('capture-page-result', (data) => {
  // Convert base64 network buffer string back to raw image binary
  const buffer = Buffer.from(data.image, 'base64');
  
  fs.writeFile(screenshotPath, buffer, (err) => {
    if (err) {
      console.error("Error saving captured page snapshot:", err);
    } else {
      console.log(`Page layout snap successfully written to: ${screenshotPath}`);
    }
  });
});
```

{% endcode %}

## Renderer (`index.html`)

{% code lineNumbers="true" %}

```html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Hello World Test</title>
</head>
<body>

    <button id="btn-hello">Hello World</button>
    <button id="btn-file">Read File</button>

    <script>
        const helloBtn = document.getElementById("btn-hello");
        const fileBtn = document.getElementById("btn-file");

        // 1. Outbound IPC: Triggering Main Process Events
        helloBtn.addEventListener("click", () => {
            window.ipc.send("hello-world", {
                message: "Hello from the renderer process!"
            });
        });

        fileBtn.addEventListener("click", () => {
            window.ipc.send("alert-file-data", {});
        });

        // 2. Inbound IPC: Listening for Main Process Replies
        window.ipc.on("alert-file-data-reply", (event, data) => {
            const container = document.createElement("div");
            container.className = "file-content";
            container.textContent = data;
            
            document.body.appendChild(container);
        });
    </script>
</body>
</html>
```

{% endcode %}


---

# 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://positronjs.gitbook.io/v1/get-started/example.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.
