@plitzi/sdk-server 0.35.9 → 0.36.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/CHANGELOG.md CHANGED
@@ -1,5 +1,73 @@
1
1
  # @plitzi/sdk-server
2
2
 
3
+ ## 0.36.0
4
+
5
+ ### Minor Changes
6
+
7
+ - - **An `apiContainer` can keep its browser requests in a query cache, the way react-query does.** Moving between
8
+ sections or pages used to ask the API again every time a provider was shown: a provider in a hidden section is
9
+ mounted but disabled, so showing it fired a fresh request, and a page navigation remounted it and did the same.
10
+ With the new `cache: true` an answer is kept for `staleTime` seconds (30 by default) and shared by every cached
11
+ provider asking the same thing — same method, URL, credentials and headers, the token included, so two visitors
12
+ never share one. Past its time the answer is still drawn at once and a fresh one is fetched behind it; an answer
13
+ nobody shows is forgotten after `gcTime` seconds (300 by default). A refused request (`4xx`/`5xx`) is shown but
14
+ never kept. **The cache is off unless an element asks for it**: an uncached provider behaves as before, asking on
15
+ every mount and sharing nothing.
16
+
17
+ The cache is `@plitzi/sdk-shared/queries` (`queryCache`, `useQuery`, `invalidateQueries`,
18
+ `invalidateQueriesForWrite`), a nexus store written with the per-path `ttl` of `@plitzi/nexus` 1.2.0, which every
19
+ consumer now requires. It reacts to the store's own freshness events, so anything that expires a query's path
20
+ makes the providers on screen ask again.
21
+
22
+ An answer stops counting as current before its time when the element's `performQuery` runs (it always asks
23
+ again), when a flow runs the new global `invalidateQueries` step (source `queries`: `elements`, api container ids
24
+ — a container's requests are tagged with its own id — and/or a `url` prefix), and after a write. Both write steps
25
+ gained `invalidateQueries` / `invalidateElements`: a `webHook` sent with anything but `GET`/`HEAD` refreshes the
26
+ requests to its own site by default, a completed `runServerAction` refreshes all of them by default, and either
27
+ can name containers instead or refresh nothing. A `writeRecord` refreshes all. Providers on screen ask again at
28
+ once; the rest when they are next shown. A sign-in, sign-out or change of account drops everything held. Server-driven
29
+ providers and RSC are untouched.
30
+
31
+ - **A `webHook` that reads can be cached** (`cache`, `staleTime`), in the same cache and under the same key as an api
32
+ container asking the same thing. Its declaration now lives beside it (`utility/webHookSpec`) and the authoring
33
+ catalog gathers it instead of keeping a copy. A `HEAD` is no longer sent with a body, which `fetch` refused.
34
+
35
+ - **Step params can pick several elements.** A new param type, `elementIds` (with an `elementType` filter), is drawn
36
+ in the flow editor as a picker: the matching elements of the space to add, and the picked ones as chips to remove —
37
+ an id no element answers to any more is kept and flagged. The value is a list of ids, so nobody types a
38
+ comma-separated list; `invalidateQueries.elements` and the write steps' `invalidateElements` use it, and the MCP
39
+ catalog says which element type each such param takes.
40
+
41
+ - The dev-tools' Store tab lists the paths a store holds with a TTL — how long ago each was written, what is left
42
+ of it, and a button to expire one or all of them. The query cache appears there as "Queries".
43
+
44
+ - `useApi` no longer takes `params`: nothing passed them, and a GET cannot carry a body anyway. A mock now answers
45
+ synchronously, without a loading frame, and a provider whose URL has not resolved asks for nothing.
46
+
47
+ ### Patch Changes
48
+
49
+ - Updated dependencies
50
+ - @plitzi/plitzi-sdk@0.36.0
51
+ - @plitzi/sdk-shared@0.36.0
52
+
53
+ ## 0.35.10
54
+
55
+ ### Patch Changes
56
+
57
+ - **Breaking:** the space setting that lets a published site open the dev tools is now `settings.debugMode`, and
58
+ `settings.devTools` is gone.
59
+
60
+ It was always the same decision the SDK and the page server call `debugMode` — whether the dev-tools panel is
61
+ authorized — and having a third name for it invited confusing it with `devMode`, which is a different thing: it turns a
62
+ deployment into a development server (the unminified bundles, request timings, and the full action trace with every
63
+ step's results). A space can authorize debugging for its own site; it can never make its server a development one.
64
+
65
+ A space that stored `settings.devTools` needs it moved to `settings.debugMode`; nothing reads the old key.
66
+
67
+ - Updated dependencies
68
+ - @plitzi/plitzi-sdk@0.35.10
69
+ - @plitzi/sdk-shared@0.35.10
70
+
3
71
  ## 0.35.9
4
72
 
5
73
  ### Patch Changes
@@ -3,13 +3,13 @@ type DebugConfig = {
3
3
  debugMode?: boolean;
4
4
  devMode?: boolean;
5
5
  };
6
- type DebugSettings = Pick<Schema['settings'], 'devTools'> | undefined;
6
+ type DebugSettings = Pick<Schema['settings'], 'debugMode'> | undefined;
7
7
  /**
8
8
  * Whether a page — and what its flows did — may be debugged. One rule for the render and for every run it reports.
9
9
  *
10
10
  * The server decides first, through `debugMode`: set, it speaks for every space, and `false` is a refusal no space can
11
11
  * turn around. Left unset, a development server authorizes it, and so does a space whose own settings switched
12
- * `devTools` on. The settings are what this server loaded, never anything the request carries.
12
+ * `debugMode` on. The settings are what this server loaded, never anything the request carries.
13
13
  *
14
14
  * A page nobody authorized is told nothing: not the steps behind it, not even that a flow ran.
15
15
  */
@@ -4,11 +4,11 @@
4
4
  *
5
5
  * The server decides first, through `debugMode`: set, it speaks for every space, and `false` is a refusal no space can
6
6
  * turn around. Left unset, a development server authorizes it, and so does a space whose own settings switched
7
- * `devTools` on. The settings are what this server loaded, never anything the request carries.
7
+ * `debugMode` on. The settings are what this server loaded, never anything the request carries.
8
8
  *
9
9
  * A page nobody authorized is told nothing: not the steps behind it, not even that a flow ran.
10
10
  */
11
- var authorizesDebugging = (config, settings) => config.debugMode ?? (config.devMode === true || settings?.devTools === true);
11
+ var authorizesDebugging = (config, settings) => config.debugMode ?? (config.devMode === true || settings?.debugMode === true);
12
12
  /**
13
13
  * The same rule, for a request that has not loaded the space yet.
14
14
  *
@@ -547,6 +547,12 @@ var createActionRunner = (config, registry, baseFetch = fetch) => {
547
547
  }));
548
548
  if (status !== "completed" && failureHandler?.enabled) await undo(failureHandler);
549
549
  const output = returned ?? {};
550
+ /**
551
+ * Redacted again as a whole, and copied. A step's result was redacted when it landed, against the credentials
552
+ * known at that moment — a later step may have resolved one an earlier result echoed — and a step still running
553
+ * past the deadline may yet push into the live array.
554
+ */
555
+ const recordedTrace = redact([...trace]);
550
556
  await record({
551
557
  runId,
552
558
  actionId: entry.id,
@@ -554,13 +560,13 @@ var createActionRunner = (config, registry, baseFetch = fetch) => {
554
560
  environment: request.environment,
555
561
  trigger: request.trigger,
556
562
  status,
563
+ startedAt,
557
564
  durationMs: Date.now() - startedAt,
558
565
  ...request.user ? { userId: request.user.id } : {},
559
- nodes: trace.map((step) => ({
560
- id: step.node.id,
561
- action: step.node.action,
562
- status: step.status
563
- })),
566
+ steps: [...steps],
567
+ input: redact(request.input),
568
+ output: redact(output),
569
+ trace: recordedTrace,
564
570
  ...failure === void 0 ? {} : { error: redact(failure) }
565
571
  });
566
572
  if (fatal) {
@@ -23,7 +23,7 @@ var createRunLogger = (logger) => (record) => {
23
23
  trigger: record.trigger,
24
24
  status: record.status,
25
25
  ...record.userId === void 0 ? {} : { userId: record.userId },
26
- steps: record.nodes.map((node) => `${node.action}:${node.status}`),
26
+ steps: record.steps.map((step) => `${step.action}:${step.status}`),
27
27
  durationMs: record.durationMs,
28
28
  ok: record.status === "completed",
29
29
  ...record.error === void 0 ? {} : { error: record.error },
@@ -62,7 +62,7 @@ var prepareRender = async (req, config, spaceId, environment, revision, pluginMa
62
62
  * product from the same cookie on its first pass, so the markup it hydrates matches.
63
63
  *
64
64
  * Who may authorize it: the server first, through `debugMode`. When it said nothing, a development server does, and
65
- * so does the space itself (`settings.devTools`) — an owner inspecting their own published site. The space is read
65
+ * so does the space itself (`settings.debugMode`) — an owner inspecting their own published site. The space is read
66
66
  * from what this server loaded, never from the request, so a visitor has no say in it.
67
67
  */
68
68
  const debugAuthorized = !Boolean(req.query["__pt"]) && authorizesDebugging(config, schema?.settings);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@plitzi/sdk-server",
3
- "version": "0.35.9",
3
+ "version": "0.36.0",
4
4
  "license": "AGPL-3.0",
5
5
  "files": [
6
6
  "dist",
@@ -58,8 +58,8 @@
58
58
  "type": "module",
59
59
  "sideEffects": false,
60
60
  "dependencies": {
61
- "@plitzi/plitzi-sdk": "0.35.9",
62
- "@plitzi/sdk-shared": "0.35.9",
61
+ "@plitzi/plitzi-sdk": "0.36.0",
62
+ "@plitzi/sdk-shared": "0.36.0",
63
63
  "ejs": "^6.0.1",
64
64
  "esbuild": "^0.28.2",
65
65
  "jsonwebtoken": "^9.0.3",