@plitzi/sdk-shared 0.35.8 → 0.35.9

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/CHANGELOG.md CHANGED
@@ -1,5 +1,25 @@
1
1
  # @plitzi/sdk-shared
2
2
 
3
+ ## 0.35.9
4
+
5
+ ### Patch Changes
6
+
7
+ - Debug a server action's whole flow from the dev-tools, not just its answer.
8
+
9
+ A run now reports an OUTLINE of what it did: every step in order, with its task, how it ended, how long it took, and
10
+ the redacted error of the one that broke the flow — the compensation steps `flow.onFailure` ran included. It carries
11
+ nothing a step was given or returned, so it goes to any page whose debugging the deployment authorized (`devMode`, or
12
+ a space that switched dev tools on for its published site) and to no other. The full trace, with each step's results,
13
+ still reaches only an authoring request or a development server.
14
+
15
+ Runs the SERVER started while rendering a page — the ones feeding `runtime: 'server'` elements — reach the dev-tools
16
+ too, seeded into the page and added to by every `/_rsc` refresh, under the same authorization: a page nobody
17
+ authorized is not told they happened. A response carrying them is never cached. A run that died on its deadline now
18
+ reports the step it was on rather than nothing at all.
19
+
20
+ The Actions tab was rebuilt around it: filters and search over the log, a run list that names the step that broke,
21
+ and a detail panel with the flow's timeline, its compensation shown apart, and what the run carried in and out.
22
+
3
23
  ## 0.35.8
4
24
 
5
25
  ### Patch Changes
@@ -1,34 +1,35 @@
1
1
  import { authFailureFromResponse as e, reportAuthFailure as t } from "../../auth/failureChannel.mjs";
2
2
  import { hasServerElements as n } from "../../schema/serverElements.mjs";
3
- import { getPaths as r, matchRoutePath as i } from "../../navigation/routes.mjs";
3
+ import { recordRenderActionRuns as r } from "../../store/actionRuns/actionRunsRecorder.mjs";
4
+ import { getPaths as i, matchRoutePath as a } from "../../navigation/routes.mjs";
4
5
  //#region src/server/rsc/refreshRsc.ts
5
- var a = (e, t, n) => {
6
+ var o = (e, t, n) => {
6
7
  if (!e) return;
7
- let a = e.pages.reduce((t, n) => (n in e.flat && (t[n] = e.flat[n]), t), {});
8
- return i(r(a, e.pageFolders, n), t.split("?")[0], n).pageId;
9
- }, o = (e) => `rsc.data.${e}`, s = () => typeof window > "u" ? "" : `${window.location.pathname}${window.location.search}`, c = async (r, i, c, l) => {
10
- let { enabled: u, endpoint: d } = r.get("rsc") ?? {};
11
- if (!u || !d || typeof window > "u") return;
12
- let f = l ?? s(), p = r.get("schema"), m = r.get("runtime.sources.auth"), h = l ? a(p, l, !!m?.details) : r.get("navigation.currentPageId");
13
- if (p && n(p, h)) try {
14
- let n = new URLSearchParams({ location: f });
15
- i?.length && n.set("ids", i.join(",")), Object.entries(c ?? {}).forEach(([e, t]) => n.set(e, t));
16
- let a = await fetch(`${d}?${n.toString()}`, { headers: { Accept: "application/json" } });
17
- if (!a.ok) {
18
- let n = e(a.status, await a.json().catch(() => void 0));
8
+ let r = e.pages.reduce((t, n) => (n in e.flat && (t[n] = e.flat[n]), t), {});
9
+ return a(i(r, e.pageFolders, n), t.split("?")[0], n).pageId;
10
+ }, s = (e) => `rsc.data.${e}`, c = () => typeof window > "u" ? "" : `${window.location.pathname}${window.location.search}`, l = async (i, a, l, u) => {
11
+ let { enabled: d, endpoint: f } = i.get("rsc") ?? {};
12
+ if (!d || !f || typeof window > "u") return;
13
+ let p = u ?? c(), m = i.get("schema"), h = i.get("runtime.sources.auth"), g = u ? o(m, u, !!h?.details) : i.get("navigation.currentPageId");
14
+ if (m && n(m, g)) try {
15
+ let n = new URLSearchParams({ location: p });
16
+ a?.length && n.set("ids", a.join(",")), Object.entries(l ?? {}).forEach(([e, t]) => n.set(e, t));
17
+ let o = await fetch(`${f}?${n.toString()}`, { headers: { Accept: "application/json" } });
18
+ if (!o.ok) {
19
+ let n = e(o.status, await o.json().catch(() => void 0));
19
20
  n && t({
20
21
  reason: n,
21
- url: d
22
- }), r.set("rsc.stale", !0);
22
+ url: f
23
+ }), i.set("rsc.stale", !0);
23
24
  return;
24
25
  }
25
- let { serverData: s } = await a.json();
26
- r.batch(() => {
27
- i?.length ? Object.entries(s ?? {}).forEach(([e, t]) => r.set(o(e), t)) : r.set("rsc.data", s ?? {}), r.set("rsc.loaded", !0), r.set("rsc.stale", !1), r.set("rsc.location", f);
26
+ let { serverData: c, actionRuns: u } = await o.json();
27
+ u?.length && r(u), i.batch(() => {
28
+ a?.length ? Object.entries(c ?? {}).forEach(([e, t]) => i.set(s(e), t)) : i.set("rsc.data", c ?? {}), i.set("rsc.loaded", !0), i.set("rsc.stale", !1), i.set("rsc.location", p);
28
29
  });
29
30
  } catch {
30
- r.set("rsc.stale", !0);
31
+ i.set("rsc.stale", !0);
31
32
  }
32
33
  };
33
34
  //#endregion
34
- export { s as currentRscLocation, c as default, c as refreshRsc, o as rscDataPath };
35
+ export { c as currentRscLocation, l as default, l as refreshRsc, s as rscDataPath };
@@ -1,4 +1,4 @@
1
- import { ActionRunEntry } from '../../types';
1
+ import { ActionRunEntry, ActionRunSummary } from '../../types';
2
2
  /** Registered by whatever started the run, for as long as stopping it means anything. */
3
3
  export declare const registerActionCanceller: (id: string, cancel: () => void) => void;
4
4
  export declare const releaseActionCanceller: (id: string) => void;
@@ -18,6 +18,15 @@ export declare const cancelActionRun: (id: string) => void;
18
18
  * A record that only appeared on success would be missing exactly the runs somebody is looking for.
19
19
  */
20
20
  export declare const recordActionRun: (entry: Omit<ActionRunEntry, "id" | "startedAt" | "status" | "progress">) => string;
21
+ /**
22
+ * Records the runs the SERVER did while building this page, or while answering a refresh of part of it.
23
+ *
24
+ * Nobody here started them, so without this they are the one kind of run a page cannot see at all — an empty
25
+ * section and no way to learn why. Deduped by the server's own run id, because a section refreshing itself
26
+ * re-reports a run that was joined or reused rather than started again: the same run twice would leave a person
27
+ * comparing two entries that are one.
28
+ */
29
+ export declare const recordRenderActionRuns: (summaries: ActionRunSummary[]) => void;
21
30
  /** How it ended, or what it reported on the way. Unknown ids are ignored: a swept-out run is not an error. */
22
31
  export declare const updateActionRun: (id: string, patch: Partial<Omit<ActionRunEntry, "id">>) => void;
23
32
  /**
@@ -17,23 +17,38 @@ var t = 0, n = (t) => e.setState("runs", t), r = /* @__PURE__ */ new Map(), i =
17
17
  progress: [],
18
18
  cancellable: !0
19
19
  }, ...e.getState().runs].slice(0, 100)), i;
20
- }, c = (t, r) => {
20
+ }, c = (e) => ({
21
+ id: `render-${e.runId}`,
22
+ actionId: e.actionId,
23
+ mode: "render",
24
+ runId: e.runId,
25
+ status: e.status,
26
+ steps: e.steps,
27
+ progress: [],
28
+ startedAt: e.startedAt,
29
+ endedAt: e.endedAt,
30
+ ...e.error === void 0 ? {} : { error: e.error },
31
+ ...e.elementId === void 0 ? {} : { elementId: e.elementId }
32
+ }), l = (t) => {
33
+ let { runs: r } = e.getState(), i = new Set(r.map((e) => e.runId)), a = t.filter((e) => !i.has(e.runId)).map(c);
34
+ a.length !== 0 && n([...a.reverse(), ...r].slice(0, 100));
35
+ }, u = (t, r) => {
21
36
  let { runs: i } = e.getState();
22
37
  i.some((e) => e.id === t) && n(i.map((e) => e.id === t ? {
23
38
  ...e,
24
39
  ...r
25
40
  } : e));
26
- }, l = (t, r) => {
41
+ }, d = (t, r) => {
27
42
  let { runs: i } = e.getState();
28
43
  n(i.map((e) => e.id === t ? {
29
44
  ...e,
30
45
  progress: [...e.progress, r].slice(-500)
31
46
  } : e));
32
- }, u = () => {
47
+ }, f = () => {
33
48
  let t = new Set(e.getState().runs.filter((e) => e.cancellable).map((e) => e.id));
34
49
  [...r.keys()].forEach((e) => {
35
50
  t.has(e) || r.delete(e);
36
51
  }), n([]);
37
52
  };
38
53
  //#endregion
39
- export { o as cancelActionRun, u as clearActionRuns, l as recordActionProgress, s as recordActionRun, i as registerActionCanceller, a as releaseActionCanceller, c as updateActionRun };
54
+ export { o as cancelActionRun, f as clearActionRuns, d as recordActionProgress, s as recordActionRun, l as recordRenderActionRuns, i as registerActionCanceller, a as releaseActionCanceller, u as updateActionRun };
@@ -1,6 +1,6 @@
1
1
  import { default as actionRunsStore } from './actionRunsStore';
2
2
  import { default as useActionRuns } from './useActionRuns';
3
3
  export { MAX_RUNS, createActionRunsState } from './actionRunsStore';
4
- export { cancelActionRun, clearActionRuns, recordActionProgress, recordActionRun, registerActionCanceller, releaseActionCanceller, updateActionRun } from './actionRunsRecorder';
4
+ export { cancelActionRun, clearActionRuns, recordActionProgress, recordActionRun, recordRenderActionRuns, registerActionCanceller, releaseActionCanceller, updateActionRun } from './actionRunsRecorder';
5
5
  export type { UseActionRunsReturn } from './useActionRuns';
6
6
  export { actionRunsStore, useActionRuns };
@@ -1,4 +1,4 @@
1
1
  import e, { MAX_RUNS as t, createActionRunsState as n } from "./actionRunsStore.mjs";
2
- import { cancelActionRun as r, clearActionRuns as i, recordActionProgress as a, recordActionRun as o, registerActionCanceller as s, releaseActionCanceller as c, updateActionRun as l } from "./actionRunsRecorder.mjs";
3
- import u from "./useActionRuns.mjs";
4
- export { t as MAX_RUNS, e as actionRunsStore, r as cancelActionRun, i as clearActionRuns, n as createActionRunsState, a as recordActionProgress, o as recordActionRun, s as registerActionCanceller, c as releaseActionCanceller, l as updateActionRun, u as useActionRuns };
2
+ import { cancelActionRun as r, clearActionRuns as i, recordActionProgress as a, recordActionRun as o, recordRenderActionRuns as s, registerActionCanceller as c, releaseActionCanceller as l, updateActionRun as u } from "./actionRunsRecorder.mjs";
3
+ import d from "./useActionRuns.mjs";
4
+ export { t as MAX_RUNS, e as actionRunsStore, r as cancelActionRun, i as clearActionRuns, n as createActionRunsState, a as recordActionProgress, o as recordActionRun, s as recordRenderActionRuns, c as registerActionCanceller, l as releaseActionCanceller, u as updateActionRun, d as useActionRuns };
@@ -192,4 +192,4 @@ export declare const useBuilderStore: {
192
192
  <P extends "style" | "displayMode" | "runtime" | "schema" | "segments" | "render" | "styleVariant" | "rsc" | "navigation" | "actions" | "styleSelector" | "selector" | "styleState" | "theme" | "render.previewMode" | "render.debugMode" | "render.renderMode" | "render.environment" | "render.isHydrating" | "render.hydrated" | "render.overQuota" | "render.testAttributes" | "prevSchema" | "pageDefinitions" | "sources" | "style.mode" | "style.variables" | "style.platform" | "style.cache" | "style.theme" | "style.fonts" | "style.variables.color" | "style.variables.spacing" | "style.variables.shadow" | "style.variables.custom" | "style.platform.desktop" | "style.platform.tablet" | "style.platform.mobile" | `style.platform.desktop.${string}` | `style.platform.tablet.${string}` | `style.platform.mobile.${string}` | "style.theme.default" | "style.theme.schemes" | `style.theme.schemes.${number}` | `style.fonts.${number}` | `style.fonts.${number}.display` | `style.fonts.${number}.fallback` | `style.fonts.${number}.stylesheet` | `style.fonts.${number}.preload` | `style.fonts.${number}.source` | `style.fonts.${number}.family` | `style.fonts.${number}.files` | `style.fonts.${number}.weights` | `style.fonts.${number}.styles` | `style.fonts.${number}.subsets` | `style.fonts.${number}.weights.${number}` | `style.fonts.${number}.styles.${number}` | `style.fonts.${number}.subsets.${number}` | `style.fonts.${number}.files.${number}` | `style.fonts.${number}.files.${number}.style` | `style.fonts.${number}.files.${number}.format` | `style.fonts.${number}.files.${number}.weight` | `style.fonts.${number}.files.${number}.unicodeRange` | `style.fonts.${number}.files.${number}.url` | `style.fonts.${number}.files.${number}.path` | `sources.${string}` | "runtime.host" | "runtime.state" | "runtime.elements" | "runtime.sources" | `runtime.host.${string}` | `runtime.state.${string}` | `runtime.elements.${string}` | `runtime.sources.${string}` | "rsc.enabled" | "schema.flat" | "schema.definition" | "schema.settings" | "schema.rsc" | "schema.variables" | "schema.pages" | "schema.pageFolders" | `schema.flat.${string}` | "schema.definition.name" | "schema.definition.permanentUrl" | "schema.settings.keepState" | "schema.settings.stateStorage" | "schema.settings.customCss" | "schema.settings.userProvider" | "schema.settings.tokenStorage" | "schema.settings.loginUrl" | "schema.settings.userUrl" | "schema.settings.refreshUrl" | "schema.settings.logoutUrl" | "schema.settings.detailsPath" | "schema.settings.tokenPath" | "schema.settings.refreshTokenPath" | "schema.settings.expirationTimePath" | "schema.settings.refreshExpirationTimePath" | "schema.settings.sessionHintCookie" | "schema.settings.sessionExchangeUrl" | "schema.settings.sessionGate" | "schema.settings.sessionRevalidateSeconds" | "schema.settings.devTools" | "schema.rsc.enabled" | "schema.rsc.transport" | `schema.variables.${number}` | `schema.variables.${number}.type` | `schema.variables.${number}.name` | `schema.variables.${number}.value` | `schema.variables.${number}.category` | `schema.variables.${number}.subValues` | `schema.variables.${number}.subValues.${number}` | `schema.variables.${number}.subValues.${number}.value` | `schema.variables.${number}.subValues.${number}.when` | `schema.variables.${number}.subValues.${number}.when.id` | `schema.variables.${number}.subValues.${number}.when.enabled` | `schema.variables.${number}.subValues.${number}.when.combinator` | `schema.variables.${number}.subValues.${number}.when.rules` | `schema.variables.${number}.subValues.${number}.when.rules.${number}` | `schema.variables.${number}.subValues.${number}.when.rules.${number}.id` | `schema.variables.${number}.subValues.${number}.when.rules.${number}.field` | `schema.variables.${number}.subValues.${number}.when.rules.${number}.value` | `schema.variables.${number}.subValues.${number}.when.rules.${number}.operator` | `schema.variables.${number}.subValues.${number}.when.rules.${number}.enabled` | `schema.variables.${number}.subValues.${number}.when.rules.${number}.isBinding` | `schema.variables.${number}.subValues.${number}.when.rules.${number}.value.toString` | `schema.variables.${number}.subValues.${number}.when.rules.${number}.value.toLocaleString` | `schema.variables.${number}.subValues.${number}.when.rules.${number}.value.valueOf` | `schema.variables.${number}.subValues.${number}.when.rules.${number}.value.toDateString` | `schema.variables.${number}.subValues.${number}.when.rules.${number}.value.toTimeString` | `schema.variables.${number}.subValues.${number}.when.rules.${number}.value.toLocaleDateString` | `schema.variables.${number}.subValues.${number}.when.rules.${number}.value.toLocaleTimeString` | `schema.variables.${number}.subValues.${number}.when.rules.${number}.value.getTime` | `schema.variables.${number}.subValues.${number}.when.rules.${number}.value.getFullYear` | `schema.variables.${number}.subValues.${number}.when.rules.${number}.value.getUTCFullYear` | `schema.variables.${number}.subValues.${number}.when.rules.${number}.value.getMonth` | `schema.variables.${number}.subValues.${number}.when.rules.${number}.value.getUTCMonth` | `schema.variables.${number}.subValues.${number}.when.rules.${number}.value.getDate` | `schema.variables.${number}.subValues.${number}.when.rules.${number}.value.getUTCDate` | `schema.variables.${number}.subValues.${number}.when.rules.${number}.value.getDay` | `schema.variables.${number}.subValues.${number}.when.rules.${number}.value.getUTCDay` | `schema.variables.${number}.subValues.${number}.when.rules.${number}.value.getHours` | `schema.variables.${number}.subValues.${number}.when.rules.${number}.value.getUTCHours` | `schema.variables.${number}.subValues.${number}.when.rules.${number}.value.getMinutes` | `schema.variables.${number}.subValues.${number}.when.rules.${number}.value.getUTCMinutes` | `schema.variables.${number}.subValues.${number}.when.rules.${number}.value.getSeconds` | `schema.variables.${number}.subValues.${number}.when.rules.${number}.value.getUTCSeconds` | `schema.variables.${number}.subValues.${number}.when.rules.${number}.value.getMilliseconds` | `schema.variables.${number}.subValues.${number}.when.rules.${number}.value.getUTCMilliseconds` | `schema.variables.${number}.subValues.${number}.when.rules.${number}.value.getTimezoneOffset` | `schema.variables.${number}.subValues.${number}.when.rules.${number}.value.setTime` | `schema.variables.${number}.subValues.${number}.when.rules.${number}.value.setMilliseconds` | `schema.variables.${number}.subValues.${number}.when.rules.${number}.value.setUTCMilliseconds` | `schema.variables.${number}.subValues.${number}.when.rules.${number}.value.setSeconds` | `schema.variables.${number}.subValues.${number}.when.rules.${number}.value.setUTCSeconds` | `schema.variables.${number}.subValues.${number}.when.rules.${number}.value.setMinutes` | `schema.variables.${number}.subValues.${number}.when.rules.${number}.value.setUTCMinutes` | `schema.variables.${number}.subValues.${number}.when.rules.${number}.value.setHours` | `schema.variables.${number}.subValues.${number}.when.rules.${number}.value.setUTCHours` | `schema.variables.${number}.subValues.${number}.when.rules.${number}.value.setDate` | `schema.variables.${number}.subValues.${number}.when.rules.${number}.value.setUTCDate` | `schema.variables.${number}.subValues.${number}.when.rules.${number}.value.setMonth` | `schema.variables.${number}.subValues.${number}.when.rules.${number}.value.setUTCMonth` | `schema.variables.${number}.subValues.${number}.when.rules.${number}.value.setFullYear` | `schema.variables.${number}.subValues.${number}.when.rules.${number}.value.setUTCFullYear` | `schema.variables.${number}.subValues.${number}.when.rules.${number}.value.toUTCString` | `schema.variables.${number}.subValues.${number}.when.rules.${number}.value.toISOString` | `schema.variables.${number}.subValues.${number}.when.rules.${number}.value.toJSON` | `schema.pages.${number}` | `schema.pageFolders.${number}` | `schema.pageFolders.${number}.id` | `schema.pageFolders.${number}.name` | `schema.pageFolders.${number}.parentId` | `schema.pageFolders.${number}.slug` | `segments.${string}` | "rsc.data" | "rsc.endpoint" | "rsc.loaded" | "rsc.stale" | "rsc.location" | "navigation.routeParams" | "navigation.queryParams" | "navigation.hostname" | "navigation.urlSearchParams" | "navigation.origin" | "navigation.currentPageId" | "navigation.navigate" | `navigation.routeParams.${string}` | `navigation.queryParams.${string}` | "navigation.urlSearchParams.toString" | "navigation.urlSearchParams.sort" | "navigation.urlSearchParams.forEach" | "navigation.urlSearchParams.entries" | "navigation.urlSearchParams.keys" | "navigation.urlSearchParams.values" | "navigation.urlSearchParams.set" | "navigation.urlSearchParams.delete" | "navigation.urlSearchParams.append" | "navigation.urlSearchParams.get" | "navigation.urlSearchParams.has" | "navigation.urlSearchParams.getAll" | "navigation.urlSearchParams.size" | "actions.endpoint" | "actions.catalog" | "actions.available" | `actions.catalog.${number}` | `actions.catalog.${number}.name` | `actions.catalog.${number}.input` | `actions.catalog.${number}.identifier` | "theme.mode" | "theme.resolved" | "theme.areas" | `theme.areas.${string}` | "prevSchema.flat" | "prevSchema.definition" | "prevSchema.settings" | "prevSchema.rsc" | "prevSchema.variables" | "prevSchema.pages" | "prevSchema.pageFolders" | `prevSchema.flat.${string}` | "prevSchema.definition.name" | "prevSchema.definition.permanentUrl" | "prevSchema.settings.keepState" | "prevSchema.settings.stateStorage" | "prevSchema.settings.customCss" | "prevSchema.settings.userProvider" | "prevSchema.settings.tokenStorage" | "prevSchema.settings.loginUrl" | "prevSchema.settings.userUrl" | "prevSchema.settings.refreshUrl" | "prevSchema.settings.logoutUrl" | "prevSchema.settings.detailsPath" | "prevSchema.settings.tokenPath" | "prevSchema.settings.refreshTokenPath" | "prevSchema.settings.expirationTimePath" | "prevSchema.settings.refreshExpirationTimePath" | "prevSchema.settings.sessionHintCookie" | "prevSchema.settings.sessionExchangeUrl" | "prevSchema.settings.sessionGate" | "prevSchema.settings.sessionRevalidateSeconds" | "prevSchema.settings.devTools" | "prevSchema.rsc.enabled" | "prevSchema.rsc.transport" | `prevSchema.variables.${number}` | `prevSchema.variables.${number}.type` | `prevSchema.variables.${number}.name` | `prevSchema.variables.${number}.value` | `prevSchema.variables.${number}.category` | `prevSchema.variables.${number}.subValues` | `prevSchema.variables.${number}.subValues.${number}` | `prevSchema.variables.${number}.subValues.${number}.value` | `prevSchema.variables.${number}.subValues.${number}.when` | `prevSchema.variables.${number}.subValues.${number}.when.id` | `prevSchema.variables.${number}.subValues.${number}.when.enabled` | `prevSchema.variables.${number}.subValues.${number}.when.combinator` | `prevSchema.variables.${number}.subValues.${number}.when.rules` | `prevSchema.variables.${number}.subValues.${number}.when.rules.${number}` | `prevSchema.variables.${number}.subValues.${number}.when.rules.${number}.id` | `prevSchema.variables.${number}.subValues.${number}.when.rules.${number}.field` | `prevSchema.variables.${number}.subValues.${number}.when.rules.${number}.value` | `prevSchema.variables.${number}.subValues.${number}.when.rules.${number}.operator` | `prevSchema.variables.${number}.subValues.${number}.when.rules.${number}.enabled` | `prevSchema.variables.${number}.subValues.${number}.when.rules.${number}.isBinding` | `prevSchema.variables.${number}.subValues.${number}.when.rules.${number}.value.toString` | `prevSchema.variables.${number}.subValues.${number}.when.rules.${number}.value.toLocaleString` | `prevSchema.variables.${number}.subValues.${number}.when.rules.${number}.value.valueOf` | `prevSchema.variables.${number}.subValues.${number}.when.rules.${number}.value.toDateString` | `prevSchema.variables.${number}.subValues.${number}.when.rules.${number}.value.toTimeString` | `prevSchema.variables.${number}.subValues.${number}.when.rules.${number}.value.toLocaleDateString` | `prevSchema.variables.${number}.subValues.${number}.when.rules.${number}.value.toLocaleTimeString` | `prevSchema.variables.${number}.subValues.${number}.when.rules.${number}.value.getTime` | `prevSchema.variables.${number}.subValues.${number}.when.rules.${number}.value.getFullYear` | `prevSchema.variables.${number}.subValues.${number}.when.rules.${number}.value.getUTCFullYear` | `prevSchema.variables.${number}.subValues.${number}.when.rules.${number}.value.getMonth` | `prevSchema.variables.${number}.subValues.${number}.when.rules.${number}.value.getUTCMonth` | `prevSchema.variables.${number}.subValues.${number}.when.rules.${number}.value.getDate` | `prevSchema.variables.${number}.subValues.${number}.when.rules.${number}.value.getUTCDate` | `prevSchema.variables.${number}.subValues.${number}.when.rules.${number}.value.getDay` | `prevSchema.variables.${number}.subValues.${number}.when.rules.${number}.value.getUTCDay` | `prevSchema.variables.${number}.subValues.${number}.when.rules.${number}.value.getHours` | `prevSchema.variables.${number}.subValues.${number}.when.rules.${number}.value.getUTCHours` | `prevSchema.variables.${number}.subValues.${number}.when.rules.${number}.value.getMinutes` | `prevSchema.variables.${number}.subValues.${number}.when.rules.${number}.value.getUTCMinutes` | `prevSchema.variables.${number}.subValues.${number}.when.rules.${number}.value.getSeconds` | `prevSchema.variables.${number}.subValues.${number}.when.rules.${number}.value.getUTCSeconds` | `prevSchema.variables.${number}.subValues.${number}.when.rules.${number}.value.getMilliseconds` | `prevSchema.variables.${number}.subValues.${number}.when.rules.${number}.value.getUTCMilliseconds` | `prevSchema.variables.${number}.subValues.${number}.when.rules.${number}.value.getTimezoneOffset` | `prevSchema.variables.${number}.subValues.${number}.when.rules.${number}.value.setTime` | `prevSchema.variables.${number}.subValues.${number}.when.rules.${number}.value.setMilliseconds` | `prevSchema.variables.${number}.subValues.${number}.when.rules.${number}.value.setUTCMilliseconds` | `prevSchema.variables.${number}.subValues.${number}.when.rules.${number}.value.setSeconds` | `prevSchema.variables.${number}.subValues.${number}.when.rules.${number}.value.setUTCSeconds` | `prevSchema.variables.${number}.subValues.${number}.when.rules.${number}.value.setMinutes` | `prevSchema.variables.${number}.subValues.${number}.when.rules.${number}.value.setUTCMinutes` | `prevSchema.variables.${number}.subValues.${number}.when.rules.${number}.value.setHours` | `prevSchema.variables.${number}.subValues.${number}.when.rules.${number}.value.setUTCHours` | `prevSchema.variables.${number}.subValues.${number}.when.rules.${number}.value.setDate` | `prevSchema.variables.${number}.subValues.${number}.when.rules.${number}.value.setUTCDate` | `prevSchema.variables.${number}.subValues.${number}.when.rules.${number}.value.setMonth` | `prevSchema.variables.${number}.subValues.${number}.when.rules.${number}.value.setUTCMonth` | `prevSchema.variables.${number}.subValues.${number}.when.rules.${number}.value.setFullYear` | `prevSchema.variables.${number}.subValues.${number}.when.rules.${number}.value.setUTCFullYear` | `prevSchema.variables.${number}.subValues.${number}.when.rules.${number}.value.toUTCString` | `prevSchema.variables.${number}.subValues.${number}.when.rules.${number}.value.toISOString` | `prevSchema.variables.${number}.subValues.${number}.when.rules.${number}.value.toJSON` | `prevSchema.pages.${number}` | `prevSchema.pageFolders.${number}` | `prevSchema.pageFolders.${number}.id` | `prevSchema.pageFolders.${number}.name` | `prevSchema.pageFolders.${number}.parentId` | `prevSchema.pageFolders.${number}.slug` | `pageDefinitions.${string}` | "collaboration" | "connectors" | "hasServerRendering" | "urlTest" | "elementHovered" | "elementSelected" | "setHovered" | "setSelected" | "collaboration.collaborators" | "collaboration.pointers" | `collaboration.collaborators.${number}` | `collaboration.collaborators.${number}.color` | `collaboration.collaborators.${number}.user` | `collaboration.collaborators.${number}.instanceId` | `collaboration.collaborators.${number}.elementState` | `collaboration.collaborators.${number}.user.firstName` | `collaboration.collaborators.${number}.user.surName` | `collaboration.collaborators.${number}.elementState.hovered` | `collaboration.collaborators.${number}.elementState.selected` | `collaboration.collaborators.${number}.elementState.hovered.rootId` | `collaboration.collaborators.${number}.elementState.hovered.elementId` | `collaboration.collaborators.${number}.elementState.selected.rootId` | `collaboration.collaborators.${number}.elementState.selected.elementId` | `collaboration.pointers.${string}` | `connectors.${string}` | "urlTest.routeParams" | "urlTest.queryParams" | "urlTest.hostname" | `urlTest.routeParams.${string}` | `urlTest.queryParams.${string}`>(basePath: P, options?: import('@plitzi/nexus').UseStoreSetterOptions<BuilderState> | undefined): import('@plitzi/nexus').SetFromBaseFn<P extends `${infer K}.${infer Rest}` ? K extends "displayMode" | "styleVariant" | "styleSelector" | "selector" | "styleState" | keyof CommonState | "collaboration" | "connectors" | "hasServerRendering" | "urlTest" | "elementHovered" | "elementSelected" | "setHovered" | "setSelected" ? NonNullable<BuilderState>[K] extends (infer U)[] ? Rest extends `${number}.${infer R}` ? import('@plitzi/nexus').PathValue<U, R> : Rest extends `${number}` ? U : never : import('@plitzi/nexus').PathValue<NonNullable<BuilderState>[K], Rest> : never : P extends "displayMode" | "styleVariant" | "styleSelector" | "selector" | "styleState" | keyof CommonState | "collaboration" | "connectors" | "hasServerRendering" | "urlTest" | "elementHovered" | "elementSelected" | "setHovered" | "setSelected" ? NonNullable<BuilderState>[P] : never>;
193
193
  };
194
194
  export { default as useRenderSettings, useRenderOverride, DEFAULT_RENDER_SETTINGS } from './renderSettings';
195
- export { actionRunsStore, cancelActionRun, clearActionRuns, recordActionProgress, recordActionRun, registerActionCanceller, releaseActionCanceller, updateActionRun, useActionRuns } from './actionRuns';
195
+ export { actionRunsStore, cancelActionRun, clearActionRuns, recordActionProgress, recordActionRun, recordRenderActionRuns, registerActionCanceller, releaseActionCanceller, updateActionRun, useActionRuns } from './actionRuns';
@@ -1,9 +1,9 @@
1
1
  import e, { DEFAULT_RENDER_SETTINGS as t, useRenderOverride as n } from "./renderSettings.mjs";
2
2
  import r from "./actionRuns/actionRunsStore.mjs";
3
- import { cancelActionRun as i, clearActionRuns as a, recordActionProgress as o, recordActionRun as s, registerActionCanceller as c, releaseActionCanceller as l, updateActionRun as u } from "./actionRuns/actionRunsRecorder.mjs";
4
- import d from "./actionRuns/useActionRuns.mjs";
5
- import { createStoreHook as f } from "@plitzi/nexus/react";
3
+ import { cancelActionRun as i, clearActionRuns as a, recordActionProgress as o, recordActionRun as s, recordRenderActionRuns as c, registerActionCanceller as l, releaseActionCanceller as u, updateActionRun as d } from "./actionRuns/actionRunsRecorder.mjs";
4
+ import f from "./actionRuns/useActionRuns.mjs";
5
+ import { createStoreHook as p } from "@plitzi/nexus/react";
6
6
  //#region src/store/index.ts
7
- var { useStore: p, useStoreSync: m, useStoreGetter: h, useStoreSetter: g } = f(), { useStore: _, useStoreSync: v, useStoreGetter: y, useStoreSetter: b } = f(), { useStore: x, useStoreSync: S, useStoreGetter: C, useStoreSetter: w } = f();
7
+ var { useStore: m, useStoreSync: h, useStoreGetter: g, useStoreSetter: _ } = p(), { useStore: v, useStoreSync: y, useStoreGetter: b, useStoreSetter: x } = p(), { useStore: S, useStoreSync: C, useStoreGetter: w, useStoreSetter: T } = p();
8
8
  //#endregion
9
- export { t as DEFAULT_RENDER_SETTINGS, r as actionRunsStore, i as cancelActionRun, a as clearActionRuns, o as recordActionProgress, s as recordActionRun, c as registerActionCanceller, l as releaseActionCanceller, u as updateActionRun, d as useActionRuns, x as useBuilderStore, C as useBuilderStoreGetter, w as useBuilderStoreSetter, S as useBuilderStoreSync, p as useCommonStore, h as useCommonStoreGetter, g as useCommonStoreSetter, m as useCommonStoreSync, n as useRenderOverride, e as useRenderSettings, _ as useSdkStore, y as useSdkStoreGetter, b as useSdkStoreSetter, v as useSdkStoreSync };
9
+ export { t as DEFAULT_RENDER_SETTINGS, r as actionRunsStore, i as cancelActionRun, a as clearActionRuns, o as recordActionProgress, s as recordActionRun, c as recordRenderActionRuns, l as registerActionCanceller, u as releaseActionCanceller, d as updateActionRun, f as useActionRuns, S as useBuilderStore, w as useBuilderStoreGetter, T as useBuilderStoreSetter, C as useBuilderStoreSync, m as useCommonStore, g as useCommonStoreGetter, _ as useCommonStoreSetter, h as useCommonStoreSync, n as useRenderOverride, e as useRenderSettings, v as useSdkStore, b as useSdkStoreGetter, x as useSdkStoreSetter, y as useSdkStoreSync };
@@ -1,4 +1,5 @@
1
1
  import { Environment } from './CommonTypes';
2
+ import { InteractionNodeStatus } from './InteractionTypes';
2
3
  import { ElementInteraction } from './SchemaTypes';
3
4
  import { SmtpSettings } from '../actions/smtp';
4
5
  /**
@@ -314,6 +315,45 @@ export type ActionRunRecord = {
314
315
  /** Present when the run ended badly. Already redacted of credential values. */
315
316
  error?: string;
316
317
  };
318
+ /**
319
+ * One step of a server action run, as a debugger may show it to anybody allowed to debug the page.
320
+ *
321
+ * What ran, in what order, how it ended and how long it took — never what the step was given or what it returned.
322
+ * Those can hold another visitor's data or a flow's internals (an endpoint, a query), so they stay in the full trace,
323
+ * which only authoring requests and development servers receive.
324
+ */
325
+ export type ActionRunStep = {
326
+ id: string;
327
+ title: string;
328
+ /** The task it ran, e.g. `kv.increment`. */
329
+ action: string;
330
+ status: InteractionNodeStatus;
331
+ /** `undo` for `flow.onFailure` and the steps after it: they ran because the flow before them failed. */
332
+ phase: 'flow' | 'undo';
333
+ startTime: number;
334
+ endTime: number;
335
+ /** Why it failed, redacted of every credential value the run resolved. */
336
+ error?: string;
337
+ };
338
+ /**
339
+ * A run a page RENDER started, reported to a page whose debugging is authorized.
340
+ *
341
+ * Nobody in the browser sent it — the server ran it while building the page, or while answering a refresh — so this is
342
+ * the only way it reaches a debugger. The same outline a call reports, and nothing more.
343
+ */
344
+ export type ActionRunSummary = {
345
+ actionId: string;
346
+ runId: string;
347
+ trigger: 'render';
348
+ status: ActionRunStatus;
349
+ /** The server element it fed. */
350
+ elementId?: string;
351
+ startedAt: number;
352
+ endedAt: number;
353
+ steps: ActionRunStep[];
354
+ /** Why a run ended before its steps could say — a deadline, a refusal. Never a provider's own message. */
355
+ error?: string;
356
+ };
317
357
  /**
318
358
  * One message a flow asked to send.
319
359
  *
@@ -1,4 +1,4 @@
1
- import { ActionEmailConfig, ActionEntry, ActionLimits, ActionRejectReason, ActionRejectRecord, ActionRunRecord, ActionRunStatus, ActionTaskDescriptor, ActionTriggerType } from './ActionTypes';
1
+ import { ActionEmailConfig, ActionEntry, ActionLimits, ActionRejectReason, ActionRunSummary, ActionRejectRecord, ActionRunRecord, ActionRunStatus, ActionTaskDescriptor, ActionTriggerType } from './ActionTypes';
2
2
  import { Environment } from './CommonTypes';
3
3
  import { ConnectorEntry } from './ConnectorTypes';
4
4
  import { Schema } from './SchemaTypes';
@@ -855,6 +855,11 @@ export type SSRContext = {
855
855
  /** What {@link SSRAdapters.meter} answered for this request, so the render reads the decision instead of
856
856
  * asking for it a second time. */
857
857
  meter?: SSRMeterDecision;
858
+ /**
859
+ * The runs this request's server elements started, as the action resolver ran them. Read once the render or the
860
+ * refresh is done, and handed on only to a page whose debugging is authorized.
861
+ */
862
+ actionRuns?: ActionRunSummary[];
858
863
  };
859
864
  export type SSRServer = {
860
865
  listen: (port: number, host?: string) => void;
@@ -1,4 +1,4 @@
1
- import { ActionField } from './ActionTypes';
1
+ import { ActionField, ActionRunStep } from './ActionTypes';
2
2
  import { SubscriptionCollaborator, SubscriptionCollaboratorPointer } from './BuilderTypes';
3
3
  import { Environment, RenderMode } from './CommonTypes';
4
4
  import { Source } from './DataSourceTypes';
@@ -256,15 +256,16 @@ export type TracingTree = Record<string, TracingTreeNode>;
256
256
  * One server action this page started, as the dev-tools show it back.
257
257
  *
258
258
  * Recorded by the `runServerAction` step itself, so it covers what no network tab makes legible: which action was
259
- * named, in which mode, what the server answered, and — when the deployment is a dev one, which is the only time
260
- * the server sends it — the STEPS the flow ran on the other side. A `detached` run has no answer to await and a
261
- * `stream` returns before its frames arrive, so both are invisible without a record of their own.
259
+ * named, in which mode, what the server answered, and — when debugging this page is authorized — the STEPS the flow
260
+ * ran on the other side. A `detached` run has no answer to await and a `stream` returns before its frames arrive, so
261
+ * both are invisible without a record of their own; a `render` run is invisible by nature, since the server did it
262
+ * while building the page and no step here ever called it.
262
263
  */
263
264
  export type ActionRunEntry = {
264
265
  /** Local to this page: assigned when the run is SENT, which is before any server run id exists. */
265
266
  id: string;
266
267
  actionId: string;
267
- mode: 'await' | 'detached' | 'stream';
268
+ mode: 'await' | 'detached' | 'stream' | 'render';
268
269
  /** The server's own id, once it answers. Absent for a run that never reached one. */
269
270
  runId?: string;
270
271
  status: 'running' | 'completed' | 'failed' | 'accepted' | 'streaming' | 'skipped' | 'aborted';
@@ -276,7 +277,16 @@ export type ActionRunEntry = {
276
277
  output?: Record<string, unknown>;
277
278
  /** Chunks a streaming run emitted, in order. */
278
279
  progress: unknown[];
279
- /** The server-side steps, when the deployment sent them: authoring requests and dev servers only. */
280
+ /**
281
+ * What the flow DID, step by step — its order, each step's outcome, and the one that broke it.
282
+ *
283
+ * Sent to any page whose debugging is authorized, because it says nothing a step was given or returned: those
284
+ * are in the trace below.
285
+ */
286
+ steps?: ActionRunStep[];
287
+ /** The server element a `render` run fed. A page has several, and each is a different flow. */
288
+ elementId?: string;
289
+ /** The steps WITH what each one read and answered. Authoring requests and dev servers only. */
280
290
  trace?: Record<string, unknown>[];
281
291
  /**
282
292
  * Whether this run can still be stopped from the panel.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@plitzi/sdk-shared",
3
- "version": "0.35.8",
3
+ "version": "0.35.9",
4
4
  "license": "AGPL-3.0",
5
5
  "files": [
6
6
  "dist",