### Packaging Webxdc App as XDC File (Shell)
Source: https://github.com/webxdc/website/blob/main/src-docs/get_started.md
Command to package a webxdc application directory into a `.xdc` file. This involves creating a zip archive of all application files. The command assumes you are in the root directory of your webxdc app. The resulting `myapp.xdc` file can then be shared in supported messengers.
```shell
(cd PATH_TO_DIR && zip -9 --recurse-paths - *) > myapp.xdc
```
--------------------------------
### Simple Webxdc App: Sending and Receiving Messages (HTML/JavaScript)
Source: https://github.com/webxdc/website/blob/main/src-docs/get_started.md
A basic webxdc application demonstrating how to send messages to chat participants and receive updates. It uses the `webxdc.js` library to interact with the webxdc runtime. The app includes an input field for sending messages and a display area for received messages. No external dependencies are required other than the `webxdc.js` script.
```html
Send
```
--------------------------------
### Full Realtime Channel Example (JavaScript)
Source: https://github.com/webxdc/website/blob/main/src-docs/spec/joinRealtimeChannel.md
Demonstrates a complete example of using the realtime channel API. It joins a channel, sets a listener to decode and log received messages, and periodically sends encoded messages. The example leaves the channel after sending a set number of messages or includes logic to manage the sending interval.
```javascript
const realtimeChannel = window.webxdc.joinRealtimeChannel();
realtimeChannel.setListener((data) => {
console.log("Received realtime data: ", data);
const msg = new TextDecoder().decode(data);
console.log("decoded message: ", msg);
})
let numMsgs = 0
const refreshIntervalId = setInterval(() => {
const myId = window.webxdc.selfAddr;
const data = new TextEncoder().encode(`[${numMsgs}] hello from ${myId}`);
numMsgs += 1
console.log("Sending message", data);
realtimeChannel.send(data);
if (numMsgs >= 100) {
realtimeChannel.leave();
clearInterval(refreshIntervalId);
}
}, 1000)
```
--------------------------------
### Packaging a webxdc App using Zip
Source: https://context7.com/webxdc/website/llms.txt
Demonstrates how to package a webxdc application into a .xdc file, which is a ZIP archive. It includes examples of creating the archive with specific files and using a one-liner command. No external dependencies beyond standard command-line tools.
```bash
# Package a webxdc app
cd myapp/
zip -9 --recurse-paths ../myapp.xdc *
# One-liner from parent directory
(cd myapp && zip -9 --recurse-paths - ") > myapp.xdc
```
--------------------------------
### Chat Application Example using selfAddr and selfName (JavaScript)
Source: https://github.com/webxdc/website/blob/main/src-docs/spec/selfAddr_and_selfName.md
A JavaScript example demonstrating a simple chat application that utilizes `selfAddr` and `selfName`. It shows how to receive messages with sender information and send new messages, notifying other users with their display names and addresses. It relies on the `setUpdateListener` and `sendUpdate` functions.
```javascript
// Receive a message from anyone in the chat
let users = new Set();
window.webxdc.setUpdateListener((update) => {
const prompt = `${update.payload.senderName} (${update.payload.senderAddr}):`;
users.add(update.payload.senderAddr);
console.log(`${prompt} ${update.message}`);
});
// start some user interface which calls the following function for
// message sending
function sendMessage(text) {
let payload = {
senderAddr: window.webxdc.selfAddr,
senderName: window.webxdc.selfName,
message: text
};
// notify all users who ever sent a message in the chat app
let notify = {};
for (const addr of users) {
notify[addr] = `new message from ${webxdc.selfName}`;
}
window.webxdc.sendUpdate({
payload: payload,
notify: notify
});
}
```
--------------------------------
### sendUpdate Function Example
Source: https://github.com/webxdc/website/blob/main/src-docs/spec/selfAddr_and_selfName.md
An example demonstrating how to use selfAddr and selfName to send messages and notifications within a chat application.
```APIDOC
## POST sendUpdate (Example)
### Description
This example shows how to use `selfAddr` and `selfName` to send messages and notifications in a chat application. It sets up a listener for incoming messages and defines a function to send new messages, including sender information and notifications to other users.
### Method
POST
### Endpoint
N/A (Demonstrates `window.webxdc.sendUpdate()`)
### Parameters
#### Request Body
- **payload** (object) - Required - Contains sender information (`senderAddr`, `senderName`) and the message content.
- **senderAddr** (string) - Required - The unique address of the sender.
- **senderName** (string) - Required - The display name of the sender.
- **message** (string) - Required - The content of the message.
- **notify** (object) - Optional - An object where keys are recipient addresses and values are notification messages.
### Request Example
```javascript
// Assume users Set and webxdc.setUpdateListener are configured
function sendMessage(text) {
let payload = {
senderAddr: window.webxdc.selfAddr,
senderName: window.webxdc.selfName,
message: text
};
let notify = {};
for (const addr of users) {
notify[addr] = `new message from ${webxdc.selfName}`;
}
window.webxdc.sendUpdate({
payload: payload,
notify: notify
});
}
```
### Response
#### Success Response (200)
Indicates that the update was successfully sent. No specific response body is detailed in the example.
#### Response Example
(No specific response body provided for sendUpdate in the example)
```
--------------------------------
### Get User Display Name
Source: https://github.com/webxdc/website/blob/main/src-docs/spec/selfAddr_and_selfName.md
Retrieves the user's nickname or display name, which can be shown in the application's user interface.
```APIDOC
## GET selfName
### Description
Retrieves the user's nickname or display name, which can be shown in the application's user interface.
### Method
GET
### Endpoint
N/A (Client-side property)
### Parameters
None
### Request Example
```javascript
window.webxdc.selfName
```
### Response
#### Success Response (200)
- **selfName** (string) - The display name of the user.
#### Response Example
```json
"Alice"
```
```
--------------------------------
### Import Webxdc Types in TypeScript
Source: https://github.com/webxdc/website/blob/main/src-docs/faq/typing.md
Demonstrates how to import the Webxdc type definition in TypeScript files to enable autocompletion and type checking in IDEs. This requires the 'webxdc-types' node package to be installed.
```typescript
import type { Webxdc } from './webxdc.d.ts'
```
--------------------------------
### List Appending with Concurrent Operations
Source: https://github.com/webxdc/website/blob/main/src-docs/shared_state/crdts.md
Illustrates concurrent append operations on a list. Alice and Bob add elements concurrently, and Charlie adds another element later. The example highlights that concurrent appends can result in different, yet valid, orderings of elements. This is common in distributed systems where operations might not be strictly ordered.
```javascript
let list = [];
// Alice's operation
list.push(5);
// Bob's operation (concurrent with Alice's)
list.push(7);
// Charlie's operation (after becoming aware of Alice's and Bob's changes)
list.push(11);
console.log(list); // Possible outcomes: [5, 7, 11] or [7, 5, 11]
```
--------------------------------
### Initialize Yjs Document
Source: https://github.com/webxdc/website/blob/main/src-docs/shared_state/practical.md
Creates a new Yjs document, which serves as the core data structure for CRDT operations. This is the starting point for any Yjs-based application.
```javascript
import * as Y from 'yjs';
const ydoc = new Y.Doc();
```
--------------------------------
### Share Variables Between JavaScript Files (Bundler)
Source: https://github.com/webxdc/website/blob/main/src-docs/faq/debugging.md
Addresses the 'Cannot find variable' error in JavaScript when sharing variables between multiple script files. This example shows how to use a bundler (like Parcel, Webpack, or esbuild) to combine scripts into a single file, resolving scope issues. Assumes `a.js` and `b.js` are bundled together.
```javascript
// a.js
const CONFIG = { difficulty: "hard", hasCoins: true };
// b.js
if (CONFIG.difficulty == "hard") {
/** make the game harder **/
}
```
--------------------------------
### Receive Peer Updates using webxdc.setUpdateListener() in JavaScript
Source: https://context7.com/webxdc/website/llms.txt
The `setUpdateListener()` function registers a callback to process incoming updates from all peers. It can also be initialized with a specific serial number to retrieve updates since that point, enabling state reconstruction and persistence.
```javascript
let messages = [];
window.webxdc.setUpdateListener((update) => {
messages.push({
text: update.payload.text,
sender: update.payload.senderName,
timestamp: update.payload.timestamp,
serial: update.serial
});
// Render messages
renderMessages(messages);
// Check if caught up
if (update.serial === update.max_serial) {
console.log('All updates received');
hideLoadingSpinner();
}
}, 0);
```
```javascript
let gameState = {
players: {},
scores: {},
currentRound: 0
};
// Load last processed serial from storage
const lastSerial = parseInt(localStorage.getItem('lastSerial') || '0');
window.webxdc.setUpdateListener((update) => {
switch (update.payload.action) {
case 'join':
gameState.players[update.payload.addr] = update.payload.name;
gameState.scores[update.payload.addr] = 0;
break;
case 'score':
gameState.scores[update.payload.addr] += update.payload.points;
break;
case 'round':
gameState.currentRound = update.payload.round;
break;
}
// Persist progress
localStorage.setItem('lastSerial', update.serial);
localStorage.setItem('gameState', JSON.stringify(gameState));
updateUI(gameState);
}, lastSerial);
```
--------------------------------
### setUpdateListener
Source: https://github.com/webxdc/website/blob/main/src-docs/spec/setUpdateListener.md
Defines a callback function that will be invoked whenever an update is received. This function processes updates sent by any peer, including the current user. It accepts an optional `serial` parameter to specify the last known serial number, defaulting to 0. The returned promise resolves once all historical updates known at the time of calling are processed.
```APIDOC
## POST /webxdc/setUpdateListener
### Description
Sets a listener callback that receives updates sent by `sendUpdate()`. The callback is triggered for updates from any peer. The `serial` parameter indicates the last known serial number (defaults to 0). The returned promise resolves after all initial updates are processed.
### Method
POST
### Endpoint
/webxdc/setUpdateListener
### Parameters
#### Query Parameters
- **serial** (number) - Optional - The last serial number known by the client. Defaults to 0.
#### Request Body
- **callback** (function) - Required - A function that accepts an `update` object and an optional `serial` parameter.
### Request Example
```javascript
window.webxdc.setUpdateListener(function(update) {
console.log('Received update:', update);
}, 123);
```
### Response
#### Success Response (200)
- **promise** (Promise) - A promise that resolves when the listener has processed all known update messages.
#### Response Example
```json
{
"message": "Listener set successfully"
}
```
## Application update object
Each `update` object passed to the callback has the following properties:
- **update.payload** (any) - The payload data sent with `sendUpdate()`.
- **update.serial** (number) - The serial number of this update. Higher numbers indicate newer updates. Gaps may exist.
- **update.max_serial** (number) - The maximum serial number currently known. If equal to `update.serial`, this is the latest update.
- **update.info** (string) - Optional, short informational message.
- **update.href** (string) - Optional, an in-app "deep link" reference provided by the sender.
- **update.document** (string) - Optional, document name set by the sender.
- **update.summary** (string) - Optional, short text displayed beside an icon.
- **update.notify** (Array) - Optional, a list of user addresses to be notified.
```
--------------------------------
### Get User's Display Name (JavaScript)
Source: https://github.com/webxdc/website/blob/main/src-docs/spec/selfAddr_and_selfName.md
Retrieves the user's display name or nickname, which can be shown in the webxdc application's UI. This property is read-only.
```javascript
window.webxdc.selfName
```
--------------------------------
### Import Files with webxdc using then/catch
Source: https://github.com/webxdc/website/blob/main/src-docs/spec/importFiles.md
This snippet shows how to import files using the `importFiles` function with the `then/catch` Promise pattern. It includes filtering options for MIME types and extensions and logs any errors encountered. The function returns a Promise resolving to an array of File objects.
```javascript
window.webxdc.importFiles({
mimeTypes: ["text/calendar"],
extensions: [".ics"],
}).then((files) => {
/* do sth with the files */
}).catch((error) => {
console.log(error);
});
```
--------------------------------
### Import Files with webxdc using Async/Await
Source: https://github.com/webxdc/website/blob/main/src-docs/spec/importFiles.md
This snippet demonstrates how to use the `importFiles` function with `async/await` to import files, filtering by MIME types and extensions. It handles potential errors during the import process. The function returns a Promise resolving to an array of File objects.
```javascript
try {
let files = await window.webxdc.importFiles({
mimeTypes: ["text/calendar"],
extensions: [".ics"],
});
/* do sth with the files */
} catch (error) {
console.log(error);
}
```
--------------------------------
### Define Update Listener in JavaScript
Source: https://github.com/webxdc/website/blob/main/src-docs/spec/setUpdateListener.md
This snippet demonstrates how to define a listener for updates sent by other peers or the application itself using webxdc's setUpdateListener. The listener callback receives an update object containing payload, serial, max_serial, and optional fields. The function returns a promise that resolves once all initial updates are processed. It's important to note that calling setUpdateListener multiple times results in undefined behavior, with only the last invocation being effective.
```javascript
let promise = window.webxdc.setUpdateListener((update) => { /* Handle update object */ }, serial);
```
--------------------------------
### Get User Unique Address
Source: https://github.com/webxdc/website/blob/main/src-docs/spec/selfAddr_and_selfName.md
Retrieves a unique, persistent identifier for the user within the current webxdc application. This address should remain the same for the same user across sessions and devices but should differ for different webxdc applications.
```APIDOC
## GET selfAddr
### Description
Retrieves a unique, persistent identifier for the user within the current webxdc application. This address should remain the same for the same user across sessions and devices but should differ for different webxdc applications.
### Method
GET
### Endpoint
N/A (Client-side property)
### Parameters
None
### Request Example
```javascript
window.webxdc.selfAddr
```
### Response
#### Success Response (200)
- **selfAddr** (string) - The unique identifier for the user.
#### Response Example
```json
"user-id-12345"
```
```
--------------------------------
### Manifest TOML Configuration for Webxdc Apps
Source: https://github.com/webxdc/website/blob/main/src-docs/spec/format.md
This snippet shows the basic structure of a manifest.toml file for a Webxdc application. It includes essential metadata like the app's name and an optional URL for its source code. The 'name' field is mandatory, and if absent, the filename is used. The 'source_code_url' is optional and provides a link to the application's source repository.
```toml
name = "My App Name"
source_code_url = "https://example.org/orga/repo"
```
--------------------------------
### Get User's Unique Identifier (JavaScript)
Source: https://github.com/webxdc/website/blob/main/src-docs/spec/selfAddr_and_selfName.md
Obtains a unique string identifier for the user within the current webxdc application. This address is persistent across sessions and devices for the same user and application, but should be unique across different applications for the same user. It should not be displayed in the UI.
```javascript
window.webxdc.selfAddr
```
--------------------------------
### Import Files into Webxdc App using window.webxdc.importFiles()
Source: https://context7.com/webxdc/website/llms.txt
The `importFiles()` function opens a file picker for users to select files for import. It can filter by file extensions and MIME types, and supports selecting multiple files. The picker may display recent chat attachments or fall back to the system file picker. Imported files are returned as an array of File objects, each with a `.text()` method to read content.
```javascript
async function importCalendar() {
try {
const files = await window.webxdc.importFiles({
extensions: ['.ics'],
mimeTypes: ['text/calendar'],
multiple: false
});
if (files.length > 0) {
const file = files[0];
const content = await file.text();
const events = parseICS(content);
events.forEach(event => {
window.webxdc.sendUpdate({
payload: {
action: 'add-event',
event: event
},
info: `Imported event: ${event.title}`
}, '');
});
}
} catch (error) {
console.error('Import failed:', error);
}
}
```
```javascript
async function importPhotos() {
try {
const files = await window.webxdc.importFiles({
extensions: ['.jpg', '.jpeg', '.png', '.gif'],
mimeTypes: ['image/jpeg', 'image/png', 'image/gif'],
multiple: true
});
for (const file of files) {
const reader = new FileReader();
reader.onload = (e) => {
const base64 = e.target.result.split(',')[1];
window.webxdc.sendUpdate({
payload: {
action: 'add-photo',
name: file.name,
data: base64,
uploader: window.webxdc.selfAddr
},
info: `${window.webxdc.selfName} added a photo`
}, '');
};
reader.readAsDataURL(file);
}
} catch (error) {
console.error('Photo import failed:', error);
}
}
```
```javascript
async function importSettings() {
try {
const files = await window.webxdc.importFiles({
extensions: ['.json'],
mimeTypes: ['application/json']
});
if (files.length > 0) {
const content = await files[0].text();
const settings = JSON.parse(content);
applySettings(settings);
}
} catch (error) {
console.error('Settings import failed:', error);
}
}
```
--------------------------------
### window.webxdc.importFiles()
Source: https://context7.com/webxdc/website/llms.txt
Opens a file picker that allows users to select files for import into the webxdc app. Filters can limit file selection by extensions and MIME types, and multiple file selection can be enabled.
```APIDOC
## POST /webxdc/importFiles
### Description
Opens a file picker for users to select files for import into the webxdc application. Supports filtering by file extensions and MIME types, and allows for multiple file selections.
### Method
POST
### Endpoint
`window.webxdc.importFiles()`
### Parameters
#### Request Body
- **extensions** (array of strings) - Optional - An array of file extensions to filter by (e.g., `['.pdf', '.docx']`).
- **mimeTypes** (array of strings) - Optional - An array of MIME types to filter by (e.g., `['application/pdf', 'application/msword']`).
- **multiple** (boolean) - Optional - Set to `true` to allow users to select multiple files. Defaults to `false`.
### Request Example
```json
{
"extensions": [".jpg", ".png"],
"mimeTypes": ["image/jpeg", "image/png"],
"multiple": true
}
```
### Response
#### Success Response (200)
- **files** (array of File objects) - An array of selected `File` objects. Each `File` object has methods like `text()` to read its content.
#### Response Example
```json
[
{
"name": "document.pdf",
"size": 102400,
"type": "application/pdf",
"text": async () => "...file content..."
}
]
```
#### Error Handling
- `error` (object) - If an error occurs during the file import process, it will be caught in the `catch` block of the JavaScript example.
```
--------------------------------
### window.webxdc.sendToChat()
Source: https://context7.com/webxdc/website/llms.txt
Allows webxdc apps to prepare messages with files and/or text for sending to chats. The messenger prompts the user to select a destination chat and may set up the message as a draft.
```APIDOC
## POST /webxdc/sendToChat
### Description
Prepares messages with files and/or text for sending to a chat. The messenger prompts the user to select a destination chat and may set up the message as a draft.
### Method
POST
### Endpoint
`window.webxdc.sendToChat()`
### Parameters
#### Request Body
- **file** (object) - Optional - An object containing file details. Can include `name`, `plainText`, or `base64`.
- **name** (string) - Required if `file` is provided - The name of the file.
- **plainText** (string) - Required if `base64` is not provided - The content of the file as plain text.
- **base64** (string) - Required if `plainText` is not provided - The content of the file as a base64 encoded string.
- **text** (string) - Optional - The text content of the message.
### Request Example
```json
{
"file": {
"name": "report.csv",
"plainText": "col1,col2\nval1,val2"
},
"text": "Here is your report."
}
```
### Response
#### Success Response (200)
This function does not return a value upon success, but it initiates the chat message sending process.
#### Response Example
(No specific JSON response for success, the action is to open the chat composer.)
#### Error Handling
- `error` (object) - If an error occurs during the process, it will be caught in the `catch` block of the JavaScript example.
```
--------------------------------
### WebXDC App Manifest (manifest.toml)
Source: https://context7.com/webxdc/website/llms.txt
The manifest.toml file contains metadata for a WebXDC application, including its name and the URL to its source code repository.
```toml
name = "My Todo App"
source_code_url = "https://github.com/example/my-todo-app"
```
--------------------------------
### Collaborative Text Editor with Yjs, Quill, and webxdc
Source: https://context7.com/webxdc/website/llms.txt
Creates a collaborative text editor using Yjs for synchronization and Quill for the rich text interface. The 'y-quill' binding ensures seamless integration. Dependencies include 'yjs', 'y-webxdc', 'quill', and 'y-quill'.
```javascript
// Collaborative text editor with Yjs
import { WebxdcProvider } from 'y-webxdc';
import * as Y from 'yjs';
import { QuillBinding } from 'y-quill';
import Quill from 'quill';
const ydoc = new Y.Doc();
const provider = new WebxdcProvider(ydoc);
const ytext = ydoc.getText('content');
// Initialize Quill editor
const editor = new Quill('#editor', {
theme: 'snow',
placeholder: 'Start typing...'
});
// Bind Yjs text to Quill
const binding = new QuillBinding(ytext, editor);
// Yjs automatically handles:
// - Concurrent edits from multiple users
// - Character-level merge without conflicts
// - Cursor positions and selections
// - Undo/redo functionality
```
--------------------------------
### Simple Chat App (HTML and JavaScript)
Source: https://context7.com/webxdc/website/llms.txt
A minimal WebXDC application demonstrating a simple chat interface. It includes HTML for the UI and JavaScript to send and receive messages using the webxdc API. The script handles user input, sending messages with sender information and timestamps, and displaying received messages.
```html
Simple Chat
Simple Chat
```
--------------------------------
### Zone Occupancy Update Operation
Source: https://github.com/webxdc/website/blob/main/src-docs/shared_state/crdts.md
This snippet demonstrates how to update occupancy counts for different zones. It takes a zone identifier and a change in occupancy as input. This approach is suitable for scenarios where concurrent updates need to be resolved deterministically, ensuring all peers converge to the same final value.
```javascript
function update(zone, change) {
// Logic to update the occupancy count for the specified zone
console.log(`Updating zone ${zone} by ${change}`);
}
```
--------------------------------
### Join Realtime Channel (JavaScript)
Source: https://github.com/webxdc/website/blob/main/src-docs/spec/joinRealtimeChannel.md
Initializes and returns a realtime channel object for the current app. This channel is private, isolated, and ephemeral. Calling this function twice without leaving the previous channel will result in an error. Ensure the API is available using `window.webxdc.joinRealtimeChannel !== undefined`.
```javascript
const realtimeChannel = window.webxdc.joinRealtimeChannel();
```
--------------------------------
### importFiles
Source: https://github.com/webxdc/website/blob/main/src-docs/spec/importFiles.md
Allows a webxdc app to import files by opening a system or custom file picker. It supports filtering files by extensions and MIME types, and allows for single or multiple file selections.
```APIDOC
## POST /webxdc/importFiles
### Description
Initiates the file import process, opening a system or custom file picker to allow the user to select files. Supports filtering by file extensions and MIME types, and can be configured to allow multiple file selections.
### Method
POST
### Endpoint
/webxdc/importFiles
### Parameters
#### Query Parameters
- **filter** (object) - Required - An object containing filtering options for the file picker.
- **extensions** (Array) - Optional - An array of file extensions (e.g., `".txt"`, `".jpg"`) to filter the displayed files. If not provided, all files are shown.
- **mimeTypes** (Array) - Optional - An array of MIME types (e.g., `"image/png"`, `"text/plain"`) to filter the displayed files. Files matching either `extensions` or `mimeTypes` are shown. Specifying MIME types might require listing common extensions as well.
- **multiple** (boolean) - Optional - Specifies whether to allow multiple file selections. Defaults to `false`.
### Request Example
```json
{
"filter": {
"mimeTypes": ["text/calendar"],
"extensions": [".ics"],
"multiple": false
}
}
```
### Response
#### Success Response (200)
- **files** (Array) - An array of `File` objects representing the imported files.
#### Response Example
```json
[
{
"name": "example.ics",
"size": 1024,
"type": "text/calendar"
// ... other File properties
}
]
```
#### Error Handling
- **Common Errors**: The promise may reject if the user cancels the file picker or if there's an issue accessing files.
```
--------------------------------
### Collaborative To-Do List with Yjs and webxdc
Source: https://context7.com/webxdc/website/llms.txt
Implements a collaborative to-do list using Yjs for CRDT-based state synchronization. It connects to the webxdc environment, manages shared todo items and their order, and handles UI rendering. Dependencies include 'yjs' and 'y-webxdc'.
```javascript
// Collaborative to-do list with Yjs
import * as Y from 'yjs';
import { WebxdcProvider } from 'y-webxdc';
// Initialize Yjs document
const ydoc = new Y.Doc();
// Connect to webxdc (handles all sync automatically)
const provider = new WebxdcProvider(ydoc);
// Get shared data structures
const todos = ydoc.getMap('todos');
const todoOrder = ydoc.getArray('order');
// Listen for changes
todos.observe(() => {
renderTodoList();
});
todoOrder.observe(() => {
renderTodoList();
});
// Add new todo
function addTodo(title, description) {
const id = Math.random().toString(36).substring(7);
// Add to map
const todoData = new Y.Map();
todoData.set('title', title);
todoData.set('description', description);
todoData.set('complete', false);
todoData.set('createdBy', window.webxdc.selfName);
todos.set(id, todoData);
// Add to order array
todoOrder.push([id]);
}
// Toggle completion
function toggleTodo(id) {
const todo = todos.get(id);
if (todo) {
todo.set('complete', !todo.get('complete'));
}
}
// Reorder todos (no data loss on concurrent edits)
function moveTodo(id, newIndex) {
const currentIndex = todoOrder.toArray().indexOf(id);
if (currentIndex !== -1) {
todoOrder.delete(currentIndex, 1);
todoOrder.insert(newIndex, [id]);
}
}
// Render UI
function renderTodoList() {
const container = document.getElementById('todos');
container.innerHTML = '';
todoOrder.forEach(id => {
const todo = todos.get(id);
if (todo) {
const item = document.createElement('div');
item.className = todo.get('complete') ? 'todo complete' : 'todo';
item.innerHTML = '
' + todo.get('title') + '
' + todo.get('description') + '
by ' + todo.get('createdBy') + '
';
container.appendChild(item);
}
});
}
```
--------------------------------
### Include Webxdc Javascript API
Source: https://github.com/webxdc/website/blob/main/src-docs/spec/api.md
This snippet demonstrates how to include the `webxdc.js` script in an HTML5 application to activate the Webxdc API. This script is provided by the messenger and should not be included in the `.xdc` file.
```html
```
--------------------------------
### Send Messages and Files to Chat using webxdc.sendToChat()
Source: https://context7.com/webxdc/website/llms.txt
The `sendToChat()` function allows webxdc apps to prepare messages containing files and/or text for sending to any chat. The messenger will prompt the user to select a destination chat. This function may exit the app, so state should be saved beforehand. It supports sending files by name and plain text, or by name and base64 encoded data, as well as text-only messages.
```javascript
async function exportReport() {
try {
const reportData = generateReportData();
const csvContent = convertToCSV(reportData);
await window.webxdc.sendToChat({
file: {
name: `report-${new Date().toISOString()}.csv`,
plainText: csvContent
},
text: `Report generated with ${reportData.length} entries`
});
} catch (error) {
console.error('Export failed:', error);
showErrorMessage('Could not export report');
}
}
```
```javascript
async function shareDrawing(canvas) {
try {
const base64Data = canvas.toDataURL('image/png').split(',')[1];
await window.webxdc.sendToChat({
file: {
name: 'drawing.png',
base64: base64Data
},
text: 'Check out my drawing!'
});
} catch (error) {
console.error('Share failed:', error);
}
}
```
```javascript
async function shareResults() {
const results = calculateResults();
await window.webxdc.sendToChat({
text: `Quiz Results:\nScore: ${results.score}\nTime: ${results.time}s`
});
}
```
--------------------------------
### Webxdc User Identification for Chat and Document Editing (JavaScript)
Source: https://context7.com/webxdc/website/llms.txt
Demonstrates how to use `window.webxdc.selfAddr` and `window.webxdc.selfName` for user identification in a chat application and a permission-based document editor. It includes functionalities for tracking users, managing message history, and controlling document access.
```javascript
let users = new Set();
let messageHistory = [];
window.webxdc.setUpdateListener((update) => {
const senderAddr = update.payload.senderAddr;
const senderName = update.payload.senderName;
users.add(senderAddr);
messageHistory.push({
from: senderName,
addr: senderAddr,
text: update.payload.message,
isMe: senderAddr === window.webxdc.selfAddr
});
renderMessages(messageHistory);
});
function sendChatMessage(text) {
let notify = {};
for (const addr of users) {
if (addr !== window.webxdc.selfAddr) {
notify[addr] = `New message from ${window.webxdc.selfName}`;
}
}
window.webxdc.sendUpdate({
payload: {
senderAddr: window.webxdc.selfAddr,
senderName: window.webxdc.selfName,
message: text
},
notify: notify
}, '');
}
const documentOwners = {};
function createDocument(title, content) {
const docId = generateId();
documentOwners[docId] = window.webxdc.selfAddr;
window.webxdc.sendUpdate({
payload: {
action: 'create',
docId: docId,
title: title,
content: content,
owner: window.webxdc.selfAddr,
ownerName: window.webxdc.selfName
},
document: title,
info: `${window.webxdc.selfName} created "${title}"ப்புகள்`
}, '');
}
function editDocument(docId, newContent) {
if (documentOwners[docId] !== window.webxdc.selfAddr) {
alert('You do not have permission to edit this document');
return;
}
window.webxdc.sendUpdate({
payload: {
action: 'edit',
docId: docId,
content: newContent,
editor: window.webxdc.selfAddr
},
info: `${window.webxdc.selfName} edited the document`
}, '');
}
```
--------------------------------
### Share Variables Between JavaScript Files (Window Object)
Source: https://github.com/webxdc/website/blob/main/src-docs/faq/debugging.md
Demonstrates how to share variables across JavaScript files by attaching them to the global `window` object. This approach makes the variables accessible from any script in the browser's context.
```javascript
// a.js
window.CONFIG = { difficulty: "hard", hasCoins: true };
// b.js
if (window.CONFIG.difficulty == "hard") {
/** make the game harder **/
}
```
--------------------------------
### Receive and Apply Yjs Updates in webxdc
Source: https://github.com/webxdc/website/blob/main/src-docs/shared_state/practical.md
Sets up a listener for incoming updates using webxdc.setUpdateListener. It decodes the Base64 payload back into a Uint8Array and applies the update to the local Yjs document.
```javascript
webxdc.setUpdateListener((update) => {
const decoded = base64ToBytes(update.payload);
Y.applyUpdate(ydoc, decoded);
});
```
--------------------------------
### Import Webxdc Types in JavaScript with JSDoc
Source: https://github.com/webxdc/website/blob/main/src-docs/faq/typing.md
Shows how to use JSDoc comments in JavaScript files to import and reference Webxdc type definitions, enabling type checking when using tools like VS Code with '//@ts-check'.
```javascript
/**
* @typedef {import('./webxdc').Webxdc} Webxdc
*/
```
--------------------------------
### Send Message with File and Text using webxdc
Source: https://github.com/webxdc/website/blob/main/src-docs/spec/sendToChat.md
The sendToChat function prepares a message containing a file and text for the user to send. The file can be provided as a Blob, base64 string, or plain text, along with its name. The text can be modified by the user, and user decisions are not reported back to the app. The function returns a promise that may be rejected in case of errors.
```javascript
let promise = window.webxdc.sendToChat(message);
// Example usage:
window.webxdc.sendToChat({
file: {base64: "aGVsbG8=", name: "hello.txt"},
text: "This file was generated by GreatApp"
}).catch((error) => {
console.log(error);
});
```
--------------------------------
### Define Custom Application Update Payload Type
Source: https://github.com/webxdc/website/blob/main/src-docs/faq/typing.md
Illustrates how to define a custom type for your application's state update payloads and integrate it with the Webxdc type. This replaces the generic 'any' in 'Webxdc' with your specific payload structure for better type safety.
```typescript
{{#include ../webxdc.d.ts:global}}
```