@lotics/app-sdk 0.123.2 → 0.123.4

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/router.js CHANGED
@@ -2,7 +2,7 @@ import {
2
2
  isEmbedded,
3
3
  postHostNotification,
4
4
  setUrlParams
5
- } from "./chunk-WM76DHGT.js";
5
+ } from "./chunk-COWN73CO.js";
6
6
 
7
7
  // src/router.tsx
8
8
  import { useEffect } from "react";
package/dist/rpc.d.ts CHANGED
@@ -6,7 +6,10 @@ import { type UrlParams, type UrlParamsPatch } from "./url_params.js";
6
6
  * postMessage and the host, holding the member's session, calls the API.
7
7
  * Standalone: the public `/v1/apps/{id}/*` endpoints are called directly, with
8
8
  * no credentials. The bridged wire must match `app_iframe_host.tsx`:
9
- * app → host: { id, op, payload }, the first also carrying `load` (`AppLoadTiming`) when the browser states any
9
+ * app → host: { id, op, payload }, the first also carrying `reportsDrawn: true` and `load` (`AppLoadTiming`) when
10
+ * the browser states any
11
+ * app → host: { type: "drawn" }, once, after the first answer when no request has been in flight for two frames:
12
+ * the app's first screen has its data
10
13
  * host → app: { id, type: "result", data } | { id, type: "error", message }
11
14
  */
12
15
  export type RpcOp = "query" | "export" | "field_options" | "workflow" | "agentRuns" | "agentRun.get" | "agentRun.cancel" | "upload" | "file.rename" | "members" | "context" | "write_model" | "prediction_miss" | "openExternal" | "openApp" | "peekApp" | "askAi" | "urlState.get" | "urlState.set" | "folder.get" | "folder.set" | "comments.list" | "comments.create" | "comments.update" | "comments.delete" | "comments.counts" | "activity.list" | "activity.undo" | "recording.start" | "recording.stop";
@@ -29,6 +29,7 @@ export type QueryAggregate = {
29
29
  day?: string;
30
30
  sum?: string;
31
31
  };
32
+ export type QueryWriteShape = { columns: Record<string, { table_id: string; field_key: string; } | { table_id: string; via: string; target_table_id: string; field_key: string; } | null>; rows?: { table_id: string; closed: boolean; sort: { field_key: string; order: "asc" | "desc"; }[]; filter?: TableRecordFilters | undefined; } | undefined; totals?: { table_id: string; by: { output: string; field_key: string; }[]; aggregates: { output: string; operation: "min" | "unique" | "date_range" | "count" | "empty" | "filled" | "percent_empty" | "percent_filled" | "percent_unique" | "sum" | "avg" | "median" | "max" | "range" | "earliest" | "latest" | "selected" | "checked" | "unchecked" | "percent_checked" | "percent_unchecked" | "string_agg"; field_key?: string | undefined; }[]; filter?: TableRecordFilters | undefined; } | undefined; };
32
33
  export type ReportColumn = {
33
34
  /** Each row's cell by it. */
34
35
  key: string;
@@ -76,7 +77,7 @@ export type ReportReadingHead = {
76
77
  /** The read behind it was cut: its figures stand, every total over them is left out (`null`). */
77
78
  truncated: boolean;
78
79
  };
79
- export type TableField = { key: string; name: string; description: string; type: "number"; format: "number" | "currency" | "percentage"; confirm_before_update?: boolean | undefined; required?: boolean | undefined; notation?: { style: "decimal"; } | { style: "currency"; currency: string | { per_row: string; }; } | { style: "unit"; unit: string | { per_row: string; }; } | undefined; currency?: string | null | undefined; unit?: string | null | undefined; unit_field?: string | null | undefined; currency_field?: string | null | undefined; default_value?: number | null | undefined; default_from?: { link_field_key: string; field_key: string; options?: Record<string, string> | undefined; } | null | undefined; } | { key: string; name: string; description: string; type: "text"; confirm_before_update?: boolean | undefined; required?: boolean | undefined; unique?: boolean | undefined; format?: "text" | "link" | "markdown" | undefined; default_value?: string | null | undefined; default_from?: { link_field_key: string; field_key: string; options?: Record<string, string> | undefined; } | null | undefined; } | { key: string; name: string; description: string; type: "date"; confirm_before_update?: boolean | undefined; required?: boolean | undefined; format?: "date" | "datetime" | "date_range" | "datetime_range" | undefined; timezone?: string | undefined; derive_from?: "created_at" | "updated_at" | undefined; default_value?: string | null | undefined; default_from?: { link_field_key: string; field_key: string; options?: Record<string, string> | undefined; } | null | undefined; } | { key: string; name: string; description: string; type: "boolean"; confirm_before_update?: boolean | undefined; required?: boolean | undefined; default_value?: boolean | null | undefined; default_from?: { link_field_key: string; field_key: string; options?: Record<string, string> | undefined; } | null | undefined; } | { key: string; name: string; description: string; type: "select"; options: { key: string; name: string; color: "red" | "orange" | "amber" | "yellow" | "lime" | "green" | "emerald" | "teal" | "cyan" | "sky" | "blue" | "indigo" | "violet" | "purple" | "fuchsia" | "pink" | "rose" | "slate" | "gray" | "zinc" | "neutral" | "stone"; mark?: { kind: string; name: string; } | undefined; }[]; confirm_before_update?: boolean | undefined; required?: boolean | undefined; multi?: boolean | undefined; default_value?: string[] | null | undefined; default_from?: { link_field_key: string; field_key: string; options?: Record<string, string> | undefined; } | null | undefined; } | { key: string; name: string; description: string; type: "select_member"; confirm_before_update?: boolean | undefined; required?: boolean | undefined; multi?: boolean | undefined; default_value?: string[] | null | undefined; default_from?: { link_field_key: string; field_key: string; options?: Record<string, string> | undefined; } | null | undefined; } | { key: string; name: string; description: string; type: "select_record_link"; table_id: string; confirm_before_update?: boolean | undefined; required?: boolean | undefined; paired_field_key?: string | undefined; cardinality?: "one" | "many" | undefined; default_from?: { link_field_key: string; field_key: string; options?: Record<string, string> | undefined; } | null | undefined; } | { key: string; name: string; description: string; type: "rollup"; source_field_key: string; aggregate_option: { operation: "count"; field_key?: string | undefined; } | { operation: "unique" | "empty" | "filled" | "percent_empty" | "percent_filled" | "percent_unique"; field_key: string; } | { operation: "min" | "unique" | "empty" | "filled" | "percent_empty" | "percent_filled" | "percent_unique" | "sum" | "avg" | "median" | "max" | "range"; field_key: string; } | { operation: "unique" | "date_range" | "empty" | "filled" | "percent_empty" | "percent_filled" | "percent_unique" | "earliest" | "latest"; field_key: string; } | { operation: "unique" | "empty" | "filled" | "percent_empty" | "percent_filled" | "percent_unique" | "selected"; field_key: string; } | { operation: "unique" | "empty" | "filled" | "percent_empty" | "percent_filled" | "percent_unique" | "selected"; field_key: string; } | { operation: "empty" | "filled" | "percent_empty" | "percent_filled" | "selected"; field_key: string; } | { operation: "checked" | "unchecked" | "percent_checked" | "percent_unchecked"; field_key: string; } | { operation: "empty" | "filled" | "percent_empty" | "percent_filled" | "selected"; field_key: string; } | { operation: "min" | "unique" | "date_range" | "empty" | "filled" | "percent_empty" | "percent_filled" | "percent_unique" | "sum" | "avg" | "median" | "max" | "range" | "earliest" | "latest" | "checked" | "unchecked" | "percent_checked" | "percent_unchecked"; field_key: string; } | { operation: "min" | "unique" | "date_range" | "empty" | "filled" | "percent_empty" | "percent_filled" | "percent_unique" | "sum" | "avg" | "median" | "max" | "range" | "earliest" | "latest"; field_key: string; }; confirm_before_update?: boolean | undefined; required?: boolean | undefined; filter?: TableRecordFiltersGroupNode | undefined; aggregate_field_type?: "number" | "boolean" | "date" | "files" | "text" | "select" | "select_member" | "select_record_link" | "rollup" | "formula" | "lookup" | "button" | "autonumber" | undefined; aggregate_field_notation?: { style: "decimal"; } | { style: "currency"; currency: string | { per_row: string; }; } | { style: "unit"; unit: string | { per_row: string; }; } | undefined; aggregate_field_format?: string | undefined; aggregate_field_currency?: string | undefined; aggregate_field_unit?: string | undefined; aggregate_field_unit_field?: string | undefined; aggregate_field_currency_field?: string | undefined; } | { key: string; name: string; description: string; type: "lookup"; source_field_key: string; lookup_field_key: string; confirm_before_update?: boolean | undefined; required?: boolean | undefined; lookup_field_type?: "number" | "boolean" | "date" | "files" | "text" | "select" | "select_member" | "select_record_link" | "rollup" | "formula" | "lookup" | "button" | "autonumber" | undefined; lookup_field_notation?: { style: "decimal"; } | { style: "currency"; currency: string | { per_row: string; }; } | { style: "unit"; unit: string | { per_row: string; }; } | undefined; lookup_field_format?: string | undefined; lookup_field_currency?: string | undefined; lookup_field_unit?: string | undefined; lookup_field_options?: { key: string; name: string; color?: string | undefined; mark?: { kind: string; name: string; } | undefined; }[] | undefined; lookup_field_autonumber?: boolean | undefined; order_by?: { field_key: string; direction: "asc" | "desc"; } | undefined; } | { key: string; name: string; description: string; type: "files"; confirm_before_update?: boolean | undefined; required?: boolean | undefined; } | { key: string; name: string; description: string; type: "formula"; formula: { expression: string; notation?: { style: "decimal"; } | { style: "currency"; currency: string | { per_row: string; }; } | { style: "unit"; unit: string | { per_row: string; }; } | undefined; link?: true | undefined; format?: "number" | "currency" | "percentage" | "link" | undefined; currency?: string | undefined; unit?: string | undefined; unit_field?: string | undefined; currency_field?: string | undefined; options?: { key: string; name: string; color: "red" | "orange" | "amber" | "yellow" | "lime" | "green" | "emerald" | "teal" | "cyan" | "sky" | "blue" | "indigo" | "violet" | "purple" | "fuchsia" | "pink" | "rose" | "slate" | "gray" | "zinc" | "neutral" | "stone"; mark?: { kind: string; name: string; } | undefined; }[] | undefined; output_type?: "number" | "boolean" | "date" | "text" | "datetime" | "select" | undefined; volatile?: boolean | undefined; }; confirm_before_update?: boolean | undefined; required?: boolean | undefined; } | { key: string; name: string; description: string; type: "button"; text: string; confirm_before_update?: boolean | undefined; required?: boolean | undefined; workflow_id?: string | null | undefined; } | { key: string; name: string; description: string; type: "autonumber"; confirm_before_update?: boolean | undefined; required?: boolean | undefined; prefix?: string | undefined; padding?: number | undefined; template?: string | undefined; };
80
+ export type TableField = { key: string; name: string; description: string; type: "number"; format: "number" | "currency" | "percentage"; confirm_before_update?: boolean | undefined; required?: boolean | undefined; notation?: { style: "decimal"; } | { style: "currency"; currency: string | { per_row: string; }; } | { style: "unit"; unit: string | { per_row: string; }; } | undefined; currency?: string | null | undefined; unit?: string | null | undefined; unit_field?: string | null | undefined; currency_field?: string | null | undefined; default_value?: number | null | undefined; default_from?: { link_field_key: string; field_key: string; options?: Record<string, string> | undefined; } | null | undefined; } | { key: string; name: string; description: string; type: "text"; confirm_before_update?: boolean | undefined; required?: boolean | undefined; unique?: boolean | undefined; format?: "text" | "link" | "markdown" | undefined; default_value?: string | null | undefined; default_from?: { link_field_key: string; field_key: string; options?: Record<string, string> | undefined; } | null | undefined; } | { key: string; name: string; description: string; type: "date"; confirm_before_update?: boolean | undefined; required?: boolean | undefined; format?: "date" | "datetime" | "date_range" | "datetime_range" | undefined; timezone?: string | undefined; derive_from?: "created_at" | "updated_at" | undefined; default_value?: string | null | undefined; default_from?: { link_field_key: string; field_key: string; options?: Record<string, string> | undefined; } | null | undefined; } | { key: string; name: string; description: string; type: "boolean"; confirm_before_update?: boolean | undefined; required?: boolean | undefined; default_value?: boolean | null | undefined; default_from?: { link_field_key: string; field_key: string; options?: Record<string, string> | undefined; } | null | undefined; } | { key: string; name: string; description: string; type: "select"; options: { key: string; name: string; color: "red" | "orange" | "amber" | "yellow" | "lime" | "green" | "emerald" | "teal" | "cyan" | "sky" | "blue" | "indigo" | "violet" | "purple" | "fuchsia" | "pink" | "rose" | "slate" | "gray" | "zinc" | "neutral" | "stone"; mark?: { kind: string; name: string; } | undefined; }[]; confirm_before_update?: boolean | undefined; required?: boolean | undefined; multi?: boolean | undefined; default_value?: string[] | null | undefined; default_from?: { link_field_key: string; field_key: string; options?: Record<string, string> | undefined; } | null | undefined; } | { key: string; name: string; description: string; type: "select_member"; confirm_before_update?: boolean | undefined; required?: boolean | undefined; multi?: boolean | undefined; default_value?: string[] | null | undefined; default_from?: { link_field_key: string; field_key: string; options?: Record<string, string> | undefined; } | null | undefined; } | { key: string; name: string; description: string; type: "select_record_link"; table_id: string; confirm_before_update?: boolean | undefined; required?: boolean | undefined; paired_field_key?: string | undefined; cardinality?: "one" | "many" | undefined; default_from?: { link_field_key: string; field_key: string; options?: Record<string, string> | undefined; } | null | undefined; } | { key: string; name: string; description: string; type: "rollup"; source_field_key: string; aggregate_option: { operation: "count"; field_key?: string | undefined; } | { operation: "unique" | "empty" | "filled" | "percent_empty" | "percent_filled" | "percent_unique"; field_key: string; } | { operation: "min" | "unique" | "empty" | "filled" | "percent_empty" | "percent_filled" | "percent_unique" | "sum" | "avg" | "median" | "max" | "range"; field_key: string; } | { operation: "unique" | "date_range" | "empty" | "filled" | "percent_empty" | "percent_filled" | "percent_unique" | "earliest" | "latest"; field_key: string; } | { operation: "unique" | "empty" | "filled" | "percent_empty" | "percent_filled" | "percent_unique" | "selected"; field_key: string; } | { operation: "empty" | "filled" | "percent_empty" | "percent_filled" | "selected"; field_key: string; } | { operation: "checked" | "unchecked" | "percent_checked" | "percent_unchecked"; field_key: string; } | { operation: "min" | "unique" | "date_range" | "empty" | "filled" | "percent_empty" | "percent_filled" | "percent_unique" | "sum" | "avg" | "median" | "max" | "range" | "earliest" | "latest" | "checked" | "unchecked" | "percent_checked" | "percent_unchecked"; field_key: string; } | { operation: "min" | "unique" | "date_range" | "empty" | "filled" | "percent_empty" | "percent_filled" | "percent_unique" | "sum" | "avg" | "median" | "max" | "range" | "earliest" | "latest"; field_key: string; }; confirm_before_update?: boolean | undefined; required?: boolean | undefined; filter?: TableRecordFiltersGroupNode | undefined; aggregate_field_type?: "number" | "boolean" | "date" | "files" | "text" | "select" | "select_member" | "select_record_link" | "rollup" | "formula" | "lookup" | "button" | "autonumber" | undefined; aggregate_field_notation?: { style: "decimal"; } | { style: "currency"; currency: string | { per_row: string; }; } | { style: "unit"; unit: string | { per_row: string; }; } | undefined; aggregate_field_format?: string | undefined; aggregate_field_currency?: string | undefined; aggregate_field_unit?: string | undefined; aggregate_field_unit_field?: string | undefined; aggregate_field_currency_field?: string | undefined; } | { key: string; name: string; description: string; type: "lookup"; source_field_key: string; lookup_field_key: string; confirm_before_update?: boolean | undefined; required?: boolean | undefined; lookup_field_type?: "number" | "boolean" | "date" | "files" | "text" | "select" | "select_member" | "select_record_link" | "rollup" | "formula" | "lookup" | "button" | "autonumber" | undefined; lookup_field_notation?: { style: "decimal"; } | { style: "currency"; currency: string | { per_row: string; }; } | { style: "unit"; unit: string | { per_row: string; }; } | undefined; lookup_field_format?: string | undefined; lookup_field_currency?: string | undefined; lookup_field_unit?: string | undefined; lookup_field_options?: { key: string; name: string; color?: string | undefined; mark?: { kind: string; name: string; } | undefined; }[] | undefined; lookup_field_autonumber?: boolean | undefined; order_by?: { field_key: string; direction: "asc" | "desc"; } | undefined; } | { key: string; name: string; description: string; type: "files"; confirm_before_update?: boolean | undefined; required?: boolean | undefined; } | { key: string; name: string; description: string; type: "formula"; formula: { expression: string; notation?: { style: "decimal"; } | { style: "currency"; currency: string | { per_row: string; }; } | { style: "unit"; unit: string | { per_row: string; }; } | undefined; link?: true | undefined; format?: "number" | "currency" | "percentage" | "link" | undefined; currency?: string | undefined; unit?: string | undefined; unit_field?: string | undefined; currency_field?: string | undefined; options?: { key: string; name: string; color: "red" | "orange" | "amber" | "yellow" | "lime" | "green" | "emerald" | "teal" | "cyan" | "sky" | "blue" | "indigo" | "violet" | "purple" | "fuchsia" | "pink" | "rose" | "slate" | "gray" | "zinc" | "neutral" | "stone"; mark?: { kind: string; name: string; } | undefined; }[] | undefined; output_type?: "number" | "boolean" | "date" | "text" | "datetime" | "select" | undefined; volatile?: boolean | undefined; }; confirm_before_update?: boolean | undefined; required?: boolean | undefined; } | { key: string; name: string; description: string; type: "button"; text: string; confirm_before_update?: boolean | undefined; required?: boolean | undefined; workflow_id?: string | null | undefined; } | { key: string; name: string; description: string; type: "autonumber"; confirm_before_update?: boolean | undefined; required?: boolean | undefined; prefix?: string | undefined; padding?: number | undefined; template?: string | undefined; };
80
81
  export type TableRecordFilters = TableRecordFiltersConditionNode | TableRecordFiltersTraversalNode | TableRecordFiltersGroupNode;
81
82
  export type TableRecordFiltersConditionNode = { node_type: "condition"; field_key?: string | undefined; type?: string | undefined; operator: string; value?: unknown; unit_option?: string | undefined; };
82
83
  export type TableRecordFiltersGroupNode = { node_type: "group"; logic: "and" | "or"; children: (TableRecordFilters)[]; };
package/dist/written.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { type BodyTable } from "./shared_types.js";
2
2
  import type { TableField } from "./shared_types.js";
3
- import { type QueryWriteShape } from "./shared_types.js";
3
+ import type { QueryWriteShape } from "./shared_types.js";
4
4
  export type Row = Record<string, unknown>;
5
5
  /** A predicted write in the shape rows store it: an option as `["opt_…"]`, a link as `[{ id, display }]`. */
6
6
  export type Staged = {
package/docs/runtime.md CHANGED
@@ -156,6 +156,15 @@ outgoing message is targeted at that origin — a third frame can neither inject
156
156
  results nor observe payloads. A host error with no message rejects as
157
157
  `"RPC failed"`.
158
158
 
159
+ The host covers the app with its loading skeleton until the app's first screen
160
+ has its data. The SDK says so for you: its first request carries
161
+ `reportsDrawn: true`, and once every request is answered and none has been sent
162
+ for two animation frames it posts `{ type: "drawn" }` to the host, once per page.
163
+ A screen that issues its reads in its first render or effects is covered until
164
+ they land; one that starts a read later than two frames after the previous
165
+ answers is shown before it, and the host lifts the cover after a bounded time
166
+ following the first request.
167
+
159
168
  **Warning:** a bridged call has **no timeout**. An op the host doesn't
160
169
  implement does reject (`"Unknown RPC op: …"`), but a message the host drops
161
170
  without replying (a crashed handler, a malformed envelope) leaves the returned
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lotics/app-sdk",
3
- "version": "0.123.2",
3
+ "version": "0.123.4",
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": {