@lotics/app-sdk 0.126.0 → 0.127.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -93,6 +93,9 @@ function getMockAgent(alias) {
93
93
  if (!isMockMode()) return null;
94
94
  return registeredFixture?.agents?.[alias] ?? null;
95
95
  }
96
+ function getMockAgentBeat() {
97
+ return registeredFixture?.agentBeatMs;
98
+ }
96
99
  function getMockExport(alias) {
97
100
  if (!isMockMode()) return null;
98
101
  return registeredFixture?.exports?.[alias] ?? null;
@@ -10824,7 +10827,7 @@ function useAgentRun(alias) {
10824
10827
  const inflight = streamLeg(
10825
10828
  (onText) => mock === null ? rpcAgentRun({ alias, session_id: opts.sessionId, input: input ?? {} }, onText, (runId) => {
10826
10829
  runIdRef.current = runId;
10827
- }) : playMockRun(typeof mock === "function" ? mock(input ?? {}) : mock, onText),
10830
+ }) : playMockRun(typeof mock === "function" ? mock(input ?? {}) : mock, onText, getMockAgentBeat()),
10828
10831
  initialAgentRunState()
10829
10832
  );
10830
10833
  const tracked = inflight.finally(() => {
package/dist/mock.d.ts CHANGED
@@ -43,6 +43,8 @@ export interface AppFixture {
43
43
  exportApps?: Record<string, MockExportApp>;
44
44
  /** `useRecording(alias)` reads as available; `start`/`stop` change nothing. */
45
45
  recordings?: Record<string, RecordingState>;
46
+ /** How long a played agent run waits before each line it streams; a real run's pace when unset. */
47
+ agentBeatMs?: number;
46
48
  }
47
49
  export declare function registerMockFixture(fixture: AppFixture | undefined): void;
48
50
  /** The raw `?__mock=1` flag, fixture or not; false where `window.location` is absent. */
@@ -53,6 +55,8 @@ export declare function getMockRows(alias: string, call: MockQueryCall): Array<R
53
55
  export declare function getMockWorkflow(alias: string): MockWorkflow | null;
54
56
  /** Null for an unmocked alias, which runs for real. */
55
57
  export declare function getMockAgent(alias: string): MockAgent | null;
58
+ /** The pace the fixture plays agent runs at; undefined for a real run's. */
59
+ export declare function getMockAgentBeat(): number | undefined;
56
60
  /** Null for an unmocked alias, which the server exports. */
57
61
  export declare function getMockExport(alias: string): MockExport | null;
58
62
  /** Null for an unmocked key, which the server exports. */
@@ -247,8 +247,8 @@ Reads paginate two different ways, and the difference is load-bearing:
247
247
  matters — **never skips or duplicates a row as the set shifts** under concurrent inserts/deletes.
248
248
  The cursor is internal: the hook sends it and reads the next one back; you never see it. The
249
249
  server keysets the sort's column keys (the runtime `sort`, else the template's own order on the
250
- columns it projects, else the record id) and falls back to offset transparently for a `first`
251
- key it can't seek. So an infinite feed needs **no
250
+ columns it projects), breaking their ties by when each row was made, then by the record id, and
251
+ falls back to offset transparently for a `first` key it can't seek. So an infinite feed needs **no
252
252
  dedupe** — key rows by `__source_record_id` for stable React keys, not to guard against repeats.
253
253
  - **`page`, `limit`, `queryAll` and manual `rpc("query", { limit, offset })` use offset
254
254
  pagination** — count `offset` rows, skip them, return the next page. Two consequences a keyset
@@ -261,7 +261,7 @@ Shared by both:
261
261
  says the cap cut the result, so a screen can say so instead of quietly under-reporting.
262
262
  - **Always give a paginated query a deterministic order.** With no `ORDER BY` (neither in the
263
263
  template nor runtime `sort`), row order is unspecified — offset pages may overlap or skip rows
264
- even without concurrent writes, and keyset falls back to the record-id order. Sort by a stable
264
+ even without concurrent writes, and keyset falls back to the order the rows were made in. Sort by a stable
265
265
  column (unique where possible).
266
266
 
267
267
  Offset-only (`page`, `limit`, and manual `rpc`):
package/docs/queries.md CHANGED
@@ -640,8 +640,8 @@ index that is:
640
640
 
641
641
  - **diacritics- and case-insensitive** (`"da nang"` matches `"Đà Nẵng"`),
642
642
  - **trigram-indexed** (scales to large tables — unlike `contains`, which scans),
643
- - **near-total field coverage** — indexes text, number, date (ISO plus `MM/dd/yyyy` and
644
- `dd/MM/yyyy` forms), select option labels, member names, link display text, and
643
+ - **near-total field coverage** — indexes text, number, date (ISO plus `MM/dd/yyyy`,
644
+ `dd/MM/yyyy` and `15 Jan 2026` forms), select option labels, member names, link display text, and
645
645
  formula/rollup/lookup values; boolean and files cells are not indexed,
646
646
  - multi-term: the query splits on whitespace (max 10 terms), all terms must match (AND).
647
647
 
package/docs/runtime.md CHANGED
@@ -68,7 +68,8 @@ Activation is a **two-step gate** — both must hold, so demo data shipping in t
68
68
  bundle never leaks into normal traffic:
69
69
 
70
70
  1. A fixture is registered via `mount({ fixture })` (`AppFixture` type:
71
- `dist/mock.d.ts` — `{ queries?, workflows?, agents?, exports?, exportApps?, recordings? }`).
71
+ `dist/mock.d.ts` — `{ queries?, workflows?, agents?, exports?, exportApps?, recordings?, agentBeatMs? }`;
72
+ `agentBeatMs` paces each line a mocked agent run streams, a real run's pace when unset, `0` in a test).
72
73
  2. The page URL carries `?__mock=1` (exactly `1`). Without the flag the fixture
73
74
  is completely inert.
74
75
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lotics/app-sdk",
3
- "version": "0.126.0",
3
+ "version": "0.127.0",
4
4
  "description": "The SDK a Lotics custom-code app reads and writes through — typed hooks over the host bridge, cell readers, mount() and AppRouter",
5
5
  "type": "module",
6
6
  "exports": {