From fb17d0d1d5295f9c168185082d7998a591d41cc3 Mon Sep 17 00:00:00 2001 From: Helen Kwok <107752876+helenkwok@users.noreply.github.com> Date: Sat, 7 Nov 2026 10:28:03 +0800 Subject: [PATCH] gridcraft-web: say a call the app already took still finishes after a timeout --- apps/gridcraft-web/src/api.rs | 4 ++-- packaging/web/README.md | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/gridcraft-web/src/api.rs b/apps/gridcraft-web/src/api.rs index 74f7206f6..34aca8c18 100644 --- a/apps/gridcraft-web/src/api.rs +++ b/apps/gridcraft-web/src/api.rs @@ -4,7 +4,7 @@ //! The crate owns the JavaScript side (`request`, `execute`, `commands`, `docInspect`, `uiInspect`, //! `screenshot`, as promises with a timeout). This module is GridCraft's part: a [`Request`] that //! queues a [`ControlRequest`] for the app, which answers it on its next frame, and waits for the -//! reply. A call the page gave up on is released ([`Pending`]), so the app drops it unrun instead of +//! reply. A call the page gave up on is released ([`Pending`]), so the app skips it if it has not started it, instead of //! applying a command the page was told had failed. use std::sync::Arc; @@ -19,7 +19,7 @@ use serde_json::{Value, json}; const POLL_MS: i32 = 16; /// A queued control request whose reply has not arrived. Dropping it before the reply (the page's -/// timeout fired, or the call was abandoned) releases the request: the app skips it unrun. +/// timeout fired, or the call was abandoned) releases the request: the app skips it if it has not started it (one it has taken still finishes). struct Pending { reply: Receiver, state: Arc, diff --git a/packaging/web/README.md b/packaging/web/README.md index 833a64e9f..b048a5b52 100644 --- a/packaging/web/README.md +++ b/packaging/web/README.md @@ -159,7 +159,7 @@ The messages and both transports are the shared contract of [`craft-web-host`](h ### Driving it from the page (`window.gridcraft`) -Every GridCraft web build puts `window.gridcraft` on the page, from [`craft-web-api`](https://github.com/storytold/craft-libs/tree/main/crates/web-api) (storytold/craft-libs#413), the same shape in every Craft app. `gridcraft.request(method, params)` calls any method of the control channel the desktop app serves (`docs/control-protocol.md`), and `execute(command, params)`, `commands()`, `docInspect(params)`, `uiInspect(params)` and `screenshot(params)` are shortcuts for the common ones. Each returns a Promise that resolves with the method's result and rejects with an `Error`; a call the app does not answer within 30 seconds rejects, and the app drops it unrun. +Every GridCraft web build puts `window.gridcraft` on the page, from [`craft-web-api`](https://github.com/storytold/craft-libs/tree/main/crates/web-api) (storytold/craft-libs#413), the same shape in every Craft app. `gridcraft.request(method, params)` calls any method of the control channel the desktop app serves (`docs/control-protocol.md`), and `execute(command, params)`, `commands()`, `docInspect(params)`, `uiInspect(params)` and `screenshot(params)` are shortcuts for the common ones. Each returns a Promise that resolves with the method's result and rejects with an `Error`; a call the app does not answer within 30 seconds rejects, and the app skips it if it has not started it; a call the app has already taken still finishes, so a retry after a timeout can apply a command twice. ```js const book = await gridcraft.docInspect(); // sheets, used ranges, tables, charts, names, selection