@lotics/app-sdk 0.106.0 → 0.107.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/AGENTS.md CHANGED
@@ -43,7 +43,7 @@ This file is the index. The **exact type** of anything is its shipped declaratio
43
43
  - **`project` only what you render; filter server-side.** → [queries](./docs/queries.md)
44
44
  - **Never hand-roll the serialization contract** — decode cells with the typed readers, and read
45
45
  only the columns the alias projects. → [data_fetching](./docs/data_fetching.md)
46
- - **Narrow `__source_record_id` / `__source_table_id` before use** — a grouped query emits neither.
46
+ - **Narrow `__source_record_id` / `__source_table_id` before use** — a grouped query answers both as null.
47
47
  → [data_fetching](./docs/data_fetching.md)
48
48
  - **A standalone app takes its API address from the page it was served in**, never from a
49
49
  constant. → [runtime](./docs/runtime.md)
@@ -53,7 +53,7 @@ export interface UseCommentsArgs {
53
53
  }
54
54
  /**
55
55
  * `record_id` must be a real id — an empty string still fetches. Gate the
56
- * panel on a row's `__source_record_id`, which a grouped query lacks.
56
+ * panel on a row's `__source_record_id`, which a grouped query answers as null.
57
57
  *
58
58
  * ```tsx
59
59
  * // In a record screen, where an id definitionally exists:
package/dist/index.js CHANGED
@@ -24536,6 +24536,8 @@ var TOOL_INPUT_SEMANTICS = {
24536
24536
  // Also `{fld_*: value}` — a signed number rather than an item array, but the
24537
24537
  // key half is what this classification governs, so it validates the same way.
24538
24538
  increment: { kind: "record_data", table_from: "table_id" },
24539
+ // `{fld_*: [document template id, ...]}` — the key half is a field of the table, as the ops above.
24540
+ remove_made: { kind: "record_data", table_from: "table_id" },
24539
24541
  // Per-record mode — field_keys names the columns; rows holds values
24540
24542
  // positionally. Each cell's semantic depends on field_keys[i], so the
24541
24543
  // tool resolves option names at execute time. Annotated `dynamic` so the
@@ -24662,6 +24664,12 @@ var TOOL_INPUT_SEMANTICS = {
24662
24664
  aggregations: { kind: "dynamic" },
24663
24665
  group_by: { kind: "field_key_ref", table_from: "table_id" }
24664
24666
  },
24667
+ evaluate_formula: {
24668
+ table_id: { kind: "table_ref", rows: "none" },
24669
+ record_id: { kind: "record_ref" },
24670
+ // `{fld_…}` tokens of `table_id`, resolved against its fields at execute time.
24671
+ expression: { kind: "dynamic" }
24672
+ },
24665
24673
  get_record: {
24666
24674
  // Schema only takes `record_id`; table_id is optional/derived.
24667
24675
  record_id: { kind: "record_ref" },
@@ -27049,6 +27057,10 @@ function adjusted(current, items, op) {
27049
27057
  const gone = new Set(given.map(keyOf));
27050
27058
  return held2.filter((item) => !gone.has(keyOf(item)));
27051
27059
  }
27060
+ function withoutMade(current, templates) {
27061
+ const gone = new Set(asList(templates));
27062
+ return asList(current).filter((item) => !(item !== null && typeof item === "object" && "document_template_id" in item && gone.has(item.document_template_id)));
27063
+ }
27052
27064
  function note(walk, effect) {
27053
27065
  if (walk.unsure && effect.kind !== "unknown") {
27054
27066
  walk.effects.push({ kind: "unknown", table_id: effect.table_id });
@@ -27081,6 +27093,7 @@ async function predictUpdate(walk, input) {
27081
27093
  const removed = await fieldValues(walk, input.remove_from);
27082
27094
  const increments = await fieldValues(walk, input.increment);
27083
27095
  const replaced = await fieldValues(walk, input.replace);
27096
+ const unmade = await fieldValues(walk, input.remove_made);
27084
27097
  for (const id of ids) {
27085
27098
  const before = recordOf(walk, id);
27086
27099
  const cells = {};
@@ -27107,6 +27120,7 @@ async function predictUpdate(walk, input) {
27107
27120
  };
27108
27121
  relative(added, (current, given) => adjusted(current, given, "add_to"));
27109
27122
  relative(removed, (current, given) => adjusted(current, given, "remove_from"));
27123
+ relative(unmade, (current, templates) => withoutMade(current, templates));
27110
27124
  relative(increments, (current, given) => typeof given === "number" ? (typeof current === "number" ? current : 0) + given : current);
27111
27125
  if (unknown2.includes("*")) {
27112
27126
  note(walk, { kind: "unknown", table_id: table });
@@ -28302,6 +28316,9 @@ function useAgentRuns(sessionId, opts) {
28302
28316
  // src/queries.ts
28303
28317
  import { useCallback as useCallback5, useMemo as useMemo3, useState as useState3 } from "react";
28304
28318
 
28319
+ // ../shared/src/schemas/read_row.ts
28320
+ var RECORD_ID_COLUMN = "__source_record_id";
28321
+
28305
28322
  // ../shared/src/schemas/app_query_aggregate.ts
28306
28323
  var AGGREGATE_COUNT_COLUMN = "__count";
28307
28324
  var AGGREGATE_SUM_COLUMN = "__sum";
@@ -28325,6 +28342,7 @@ function aggregateRows(rows, aggregate) {
28325
28342
  return typeof value === "number" ? [value] : [];
28326
28343
  });
28327
28344
  return {
28345
+ [RECORD_ID_COLUMN]: null,
28328
28346
  ...Object.fromEntries(by.map((column) => [column, first2?.[column] ?? null])),
28329
28347
  ...day === void 0 ? {} : { [AGGREGATE_DAY_COLUMN]: dayOf(first2?.[day]) },
28330
28348
  [AGGREGATE_COUNT_COLUMN]: members2.length,
package/dist/queries.d.ts CHANGED
@@ -12,10 +12,10 @@ import type { ReportColumn, ReportReading } from "./shared_types.js";
12
12
  */
13
13
  export interface QueryRow {
14
14
  [column: string]: unknown;
15
- /** The record this row came from. Absent on a grouped/aggregated row. */
16
- __source_record_id?: string;
17
- /** The table that record lives in. Absent on a grouped/aggregated row. */
18
- __source_table_id?: string;
15
+ /** The record this row came from: null on a grouped row, which stands for no one record. */
16
+ __source_record_id?: string | null;
17
+ /** The table that record lives in: null on a grouped row. */
18
+ __source_table_id?: string | null;
19
19
  }
20
20
  /**
21
21
  * The row type of alias `K`: its projected columns plus the two addressing
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lotics/app-sdk",
3
- "version": "0.106.0",
3
+ "version": "0.107.0",
4
4
  "description": "The SDK a Lotics custom-code app reads and writes through \u2014 typed hooks over the host bridge, cell readers, mount() and AppRouter",
5
5
  "type": "module",
6
6
  "exports": {