@shwfed/config 2.7.7 → 2.8.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.
Files changed (91) hide show
  1. package/dist/mcp.mjs +128 -55
  2. package/dist/module.json +1 -1
  3. package/dist/preview/assets/{badge-B0tiCpa_.js → badge-BI1mdo92.js} +1 -1
  4. package/dist/preview/assets/{config-jDPbLgBr.js → config-BNF2r9jW.js} +1 -1
  5. package/dist/preview/assets/{config-CGvnv-5x.js → config-BxuGYvER.js} +1 -1
  6. package/dist/preview/assets/{config-GCvXe12z.js → config-Cy5w3JWQ.js} +1 -1
  7. package/dist/preview/assets/{config-BG9TRQcv.js → config-DqUnpWZk.js} +1 -1
  8. package/dist/preview/assets/{config-C-XJ-8Rs.js → config-Du5SuNSb.js} +1 -1
  9. package/dist/preview/assets/{config-Dafqx9xC.js → config-DuzQXHvg.js} +1 -1
  10. package/dist/preview/assets/{config-Bfb2sH6S.js → config-OrJljNWU.js} +1 -1
  11. package/dist/preview/assets/{config-DqMRy1WL.js → config-XgVqueyq.js} +1 -1
  12. package/dist/preview/assets/{config-DDPihojt.js → config-ggyCcWNZ.js} +1 -1
  13. package/dist/preview/assets/{definition.vue_vue_type_script_setup_true_lang-DBXfCj4Q.js → definition.vue_vue_type_script_setup_true_lang-lEhYVEcN.js} +1 -1
  14. package/dist/preview/assets/{index-D7jDE3kp.js → index-BvLLQuQr.js} +1 -1
  15. package/dist/preview/assets/{index-B0PL01fm.css → index-DsMR5NfK.css} +1 -1
  16. package/dist/preview/assets/{index-CHzOsSTW.js → index-Yv78vz4W.js} +168 -168
  17. package/dist/preview/assets/index-yrBKwEfk.js +1 -0
  18. package/dist/preview/assets/{item-DV-Garrg.js → item-DMtXi_cx.js} +1 -1
  19. package/dist/preview/assets/{runtime-DKtlQWwc.js → runtime-2S3Yr051.js} +1 -1
  20. package/dist/preview/assets/{runtime-UmLaEUGf.js → runtime-BUPuX-Gq.js} +1 -1
  21. package/dist/preview/assets/{runtime-BovPWken.js → runtime-C4jFTZ4Z.js} +1 -1
  22. package/dist/preview/assets/{runtime-DA77AmOP.js → runtime-CA58Mif7.js} +1 -1
  23. package/dist/preview/assets/{runtime-BxBBFFHA.js → runtime-CWqQzWuc.js} +1 -1
  24. package/dist/preview/assets/{runtime-D-LBi56N.js → runtime-CjJBU_e1.js} +1 -1
  25. package/dist/preview/assets/{runtime-DHTqFEQI.js → runtime-DeUmGsM_.js} +1 -1
  26. package/dist/preview/assets/{runtime-CwmJ9MLQ.js → runtime-DnXoWy2A.js} +1 -1
  27. package/dist/preview/assets/{runtime-Cyjx6haa.js → runtime-wVZ1xP8L.js} +1 -1
  28. package/dist/preview/index.html +2 -2
  29. package/dist/runtime/components/block-layout-editor/index.vue +1 -4
  30. package/dist/runtime/components/config/blocks/2026-05-06/com.shwfed.block.table/config.d.vue.ts +2 -0
  31. package/dist/runtime/components/config/blocks/2026-05-06/com.shwfed.block.table/config.vue.d.ts +2 -0
  32. package/dist/runtime/components/config/blocks/2026-05-06/com.shwfed.block.table/runtime.d.vue.ts +2 -0
  33. package/dist/runtime/components/config/blocks/2026-05-06/com.shwfed.block.table/runtime.vue.d.ts +2 -0
  34. package/dist/runtime/components/config/blocks/2026-05-06/com.shwfed.block.table/schema.d.ts +2 -0
  35. package/dist/runtime/components/config/blocks/2026-05-17/com.shwfed.block.chart.xy/config.vue +5 -0
  36. package/dist/runtime/components/config/blocks/2026-06-02/com.shwfed.block.card/config.vue +2 -0
  37. package/dist/runtime/components/config/blocks/2026-06-02/com.shwfed.block.card/schema.d.ts +5 -0
  38. package/dist/runtime/components/config/blocks/2026-06-02/com.shwfed.block.card/schema.js +8 -3
  39. package/dist/runtime/components/form/config.vue +24 -16
  40. package/dist/runtime/components/form/fields/2026-04-22/com.shwfed.form.field.markdown/runtime.vue +12 -1
  41. package/dist/runtime/components/form/fields/2026-04-22/com.shwfed.form.field.markdown/schema.d.ts +8 -2
  42. package/dist/runtime/components/form/fields/2026-04-22/com.shwfed.form.field.markdown/schema.js +3 -3
  43. package/dist/runtime/components/form/fields/2026-04-22/com.shwfed.form.field.textarea/config.d.vue.ts +2 -2
  44. package/dist/runtime/components/form/fields/2026-04-22/com.shwfed.form.field.textarea/config.vue +15 -25
  45. package/dist/runtime/components/form/fields/2026-04-22/com.shwfed.form.field.textarea/config.vue.d.ts +2 -2
  46. package/dist/runtime/components/form/fields/2026-04-22/com.shwfed.form.field.textarea/runtime.vue +11 -2
  47. package/dist/runtime/components/form/fields/2026-04-22/com.shwfed.form.field.textarea/schema.d.ts +1 -1
  48. package/dist/runtime/components/form/fields/2026-04-22/com.shwfed.form.field.textarea/schema.js +4 -4
  49. package/dist/runtime/components/form/fields/2026-05-18/com.shwfed.form.field.table/config.d.vue.ts +2 -0
  50. package/dist/runtime/components/form/fields/2026-05-18/com.shwfed.form.field.table/config.vue.d.ts +2 -0
  51. package/dist/runtime/components/form/fields/2026-05-18/com.shwfed.form.field.table/schema.d.ts +2 -0
  52. package/dist/runtime/components/form/index.vue +5 -1
  53. package/dist/runtime/components/form/schema.d.ts +1 -1
  54. package/dist/runtime/components/form/schema.js +6 -1
  55. package/dist/runtime/components/form/utils/form-vars.js +2 -0
  56. package/dist/runtime/components/form/utils/schema-meta.d.ts +2 -0
  57. package/dist/runtime/components/form/utils/schema-meta.js +24 -0
  58. package/dist/runtime/components/table/columns/2026-05-24/com.shwfed.table.column.combobox-single.remote.options-remote/config.d.vue.ts +2 -2
  59. package/dist/runtime/components/table/columns/2026-05-24/com.shwfed.table.column.combobox-single.remote.options-remote/config.vue.d.ts +2 -2
  60. package/dist/runtime/components/table/columns/2026-05-24/com.shwfed.table.column.combobox-single.remote.options-static/config.d.vue.ts +2 -2
  61. package/dist/runtime/components/table/columns/2026-05-24/com.shwfed.table.column.combobox-single.remote.options-static/config.vue.d.ts +2 -2
  62. package/dist/runtime/components/table/columns/2026-05-25/com.shwfed.table.column.combobox-multi.remote.options-remote/config.d.vue.ts +2 -2
  63. package/dist/runtime/components/table/columns/2026-05-25/com.shwfed.table.column.combobox-multi.remote.options-remote/config.vue.d.ts +2 -2
  64. package/dist/runtime/components/table/columns/2026-05-25/com.shwfed.table.column.combobox-multi.remote.options-static/config.d.vue.ts +2 -2
  65. package/dist/runtime/components/table/columns/2026-05-25/com.shwfed.table.column.combobox-multi.remote.options-static/config.vue.d.ts +2 -2
  66. package/dist/runtime/components/table/columns/2026-05-26/com.shwfed.table.column.combobox-multi.remote/config.d.vue.ts +2 -2
  67. package/dist/runtime/components/table/columns/2026-05-26/com.shwfed.table.column.combobox-multi.remote/config.vue.d.ts +2 -2
  68. package/dist/runtime/components/table/columns/2026-05-26/com.shwfed.table.column.combobox-single.remote/config.d.vue.ts +2 -2
  69. package/dist/runtime/components/table/columns/2026-05-26/com.shwfed.table.column.combobox-single.remote/config.vue.d.ts +2 -2
  70. package/dist/runtime/components/table/columns/2026-05-28/com.shwfed.table.column.combobox-multi/config.d.vue.ts +2 -2
  71. package/dist/runtime/components/table/columns/2026-05-28/com.shwfed.table.column.combobox-multi/config.vue.d.ts +2 -2
  72. package/dist/runtime/components/table/columns/2026-05-28/com.shwfed.table.column.combobox-single/config.d.vue.ts +2 -2
  73. package/dist/runtime/components/table/columns/2026-05-28/com.shwfed.table.column.combobox-single/config.vue.d.ts +2 -2
  74. package/dist/runtime/components/table/config.vue +30 -36
  75. package/dist/runtime/components/table/index.d.vue.ts +2 -0
  76. package/dist/runtime/components/table/index.vue +8 -0
  77. package/dist/runtime/components/table/index.vue.d.ts +2 -0
  78. package/dist/runtime/components/table/schema.d.ts +4 -0
  79. package/dist/runtime/components/table/schema.js +4 -0
  80. package/dist/runtime/components/ui/expression-editor/ExpressionEditor.d.vue.ts +4 -3
  81. package/dist/runtime/components/ui/expression-editor/ExpressionEditor.vue +135 -111
  82. package/dist/runtime/components/ui/expression-editor/ExpressionEditor.vue.d.ts +4 -3
  83. package/dist/runtime/share/expression.d.ts +23 -0
  84. package/dist/runtime/share/expression.js +37 -17
  85. package/dist/runtime/share/use-persisted-query.d.ts +21 -0
  86. package/dist/runtime/share/use-persisted-query.js +33 -0
  87. package/dist/runtime/vendor/cel-js/CLAUDE.md +2 -2
  88. package/dist/runtime/vendor/cel-js/PROMPT.md +15 -6
  89. package/dist/runtime/vendor/cel-js/lib/macros.js +66 -14
  90. package/package.json +1 -1
  91. package/dist/preview/assets/index-CSfKAdi7.js +0 -1
@@ -0,0 +1,21 @@
1
+ import { type Ref } from 'vue';
2
+ import type { FormState } from '../components/form/utils/state.js';
3
+ /**
4
+ * Mirrors a table's query form state into `sessionStorage` so filters survive
5
+ * a page reload — until the tab is closed / the user leaves the site.
6
+ *
7
+ * Modeled on `useActiveTabId`: storage is keyed on the table's stable
8
+ * `config.id`, every access is guarded against SSR and unavailable storage
9
+ * (privacy modes), and `restore()` is meant to run in `onMounted` after the
10
+ * form's CEL `initial` seed has landed so the stored value overrides it.
11
+ *
12
+ * - `restore()` applies a stored snapshot onto `queryState` (no-op when
13
+ * disabled, when there is no `tableId`, or when nothing is stored).
14
+ * - `clear()` drops the stored snapshot (used by `reset-query`, so a reset is
15
+ * authoritative and the stale query does not reappear on the next load).
16
+ * - A deep watch persists live changes while enabled.
17
+ */
18
+ export declare function usePersistedQuery(tableId: string | undefined, queryState: Ref<FormState>, enabled: () => boolean): {
19
+ restore: () => void;
20
+ clear: () => void;
21
+ };
@@ -0,0 +1,33 @@
1
+ import { watch } from "vue";
2
+ const STORAGE_PREFIX = "shwfed.table.query.";
3
+ export function usePersistedQuery(tableId, queryState, enabled) {
4
+ const active = () => Boolean(tableId) && enabled() && typeof window !== "undefined";
5
+ const key = () => `${STORAGE_PREFIX}${tableId}`;
6
+ function restore() {
7
+ if (!active()) return;
8
+ try {
9
+ const raw = window.sessionStorage.getItem(key());
10
+ if (!raw) return;
11
+ const parsed = JSON.parse(raw);
12
+ if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
13
+ queryState.value = parsed;
14
+ }
15
+ } catch {
16
+ }
17
+ }
18
+ function clear() {
19
+ if (!tableId || typeof window === "undefined") return;
20
+ try {
21
+ window.sessionStorage.removeItem(key());
22
+ } catch {
23
+ }
24
+ }
25
+ watch(queryState, (next) => {
26
+ if (!active()) return;
27
+ try {
28
+ window.sessionStorage.setItem(key(), JSON.stringify(next));
29
+ } catch {
30
+ }
31
+ }, { deep: true });
32
+ return { restore, clear };
33
+ }
@@ -18,7 +18,7 @@ A `range()` built-in has been added (not from upstream) — `range(number, numbe
18
18
 
19
19
  The `homogeneousAggregateLiterals` and `enableOptionalTypes` environment options have been removed. Aggregate data structures (lists, maps) are always heterogeneous — mixed-type literals are inferred as `list<dyn>` or `map<dyn, dyn>`. Optional types (`.?`, `[?]`, `optional.*` helpers) are always enabled.
20
20
 
21
- The custom `Optional` class has been replaced with Effect's `Option` type (`import { Option } from 'effect'`). Internal helpers `optionalOf(value)` and `optionalValue(opt)` in `optional.js` handle the CEL-specific semantics (treating `undefined` as `None`, throwing `EvaluationError` on missing value access). The optional surface is `optional.of(A): optional<A>` (the lift / `pure`), `optional.none()`, `optional.hasValue()`, `optional.value()`, `optional.or(optional)`, `optional.orValue(value)`, plus `optional<A>.flatMap(var, body): optional<B>` monadic bind, a local addition (not from upstream). `flatMap` is a variable-binding macro (registered with `(ast, ast)` arg types so its body stays unevaluated): on `Some` it binds the value and evaluates `body` (which must itself yield an `optional`); on `None` it short-circuits without touching `body`. Map (`fmap`) is the derived `o.flatMap(v, optional.of(f(v)))`.
21
+ The custom `Optional` class has been replaced with Effect's `Option` type (`import { Option } from 'effect'`). Internal helpers `optionalOf(value)` and `optionalValue(opt)` in `optional.js` handle the CEL-specific semantics (treating `undefined` as `None`, throwing `EvaluationError` on missing value access). The optional surface is `optional.of(A): optional<A>` (the lift / `pure`), `optional.none()`, `optional.hasValue()`, `optional.value()`, `optional.or(optional)`, `optional.orValue(value)`, plus `optional<A>.flatMap(var, body): optional<B>` (monadic bind) and `optional<A>.map(var, body): optional<B>` (the Functor `fmap`) — all local additions (not from upstream). Both are variable-binding macros (registered with `(ast, ast)` arg types so the body stays unevaluated): on `Some` they bind the value and evaluate `body`; on `None` they short-circuit without touching `body`. `flatMap`'s body must itself yield an `optional`; `map`'s body is a plain value that gets re-wrapped in `Some`. `map` is the derived `o.flatMap(v, optional.of(body))` promoted to a first-class macro. NOTE: `map` is **registered in `macros.ts`**, not here — the parser resolves a macro by name before types are known, so the optional `map` and the list-comprehension `map` must share one expander that dispatches on the receiver type at type-check (an `optional` receiver → fmap; `list`/`map` → comprehension; a `dyn` receiver is deferred to a runtime `Option.isOption` check).
22
22
 
23
23
  An `http` built-in has been added (`http-builtins.ts`, `http-builder.ts`) — not from upstream. It registers the `http` constant and the `http` / `HttpRequest` types on `globalRegistry`, so `http.get(url).header(...).body(...)` expressions type-check and evaluate in every `Environment`. A CEL expression only builds an `HttpRequestBuilder` — a pure description of a request; it never issues one. Both terminal methods, `.json()` and `.file()`, are dispatched by the host on the returned builder (neither is a CEL method), so expression evaluation stays free of IO. Endpoints must be absolute URLs — there is no base-URL resolution. Depends on `fx-fetch`. The host can register process-wide default headers via `HttpRequestBuilder.setDefaultHeader(name, valueOrGetter)` / `clearDefaultHeader(name)`; they are merged in at `#buildRequest()` time, with case-insensitive precedence to an explicit `.header(...)` on the builder. A getter that returns `null` / `undefined` / `''` skips the header for that request, so the host can source values from live refs (e.g. the active i18n locale for `Accept-Language`) without baking in stale snapshots.
24
24
 
@@ -41,7 +41,7 @@ lib/
41
41
  ├── operators.ts — Binary/unary operator implementations
42
42
  ├── overloads.ts — Operator overload definitions
43
43
  ├── functions.ts — Built-in functions + Date type (TZDate)
44
- ├── macros.ts — map, filter, all, exists, exists_one, find, has, cel.bind
44
+ ├── macros.ts — map (list comprehension + optional fmap), filter, all, exists, exists_one, find, has, cel.bind
45
45
  ├── http-builtins.ts — `http` constant + http/HttpRequest types (local addition)
46
46
  ├── http-builder.ts — `HttpRequestBuilder` — what an http.* expression returns
47
47
  ├── json-builtins.ts — `JSON` constant + `JSON.parse` / `JSON.stringify` (local addition)
@@ -316,18 +316,27 @@ o.orValue(default) // unwrap, or `default` when absent
316
316
  o.or(otherOptional) // first present optional wins
317
317
  ```
318
318
 
319
- ### flatMapchain a computation that may itself be absent
320
- `o.flatMap(v, body)` binds the present value to `v` and evaluates `body` which
321
- must itself return an `optional` only when `o` is present; an absent `o`
319
+ ### maptransform a present value
320
+ `o.map(v, body)` binds the present value to `v`, evaluates `body` (a plain value),
321
+ and re-wraps the result as present, only when `o` is present; an absent `o`
322
322
  short-circuits to `None` and `body` is never evaluated.
323
323
  ```cel
324
- loc.query("id").flatMap(v, optional.of("user-" + v)).orValue("anon")
324
+ loc.query("id").map(v, "user-" + v).orValue("anon")
325
325
  // "user-42" when ?id=42 is present; "anon" when absent
326
+ ```
327
+
328
+ ### flatMap — chain a computation that may itself be absent
329
+ `o.flatMap(v, body)` is like `map`, but `body` must itself return an `optional`
330
+ (so it can decide the result is absent). Use `flatMap` when the next step can
331
+ fail; use `map` when it always produces a value.
332
+ ```cel
333
+ loc.query("id").flatMap(v, optional.of("user-" + v)).orValue("anon")
334
+ // same as the map example above
326
335
 
327
336
  optional.of(2).flatMap(v, optional.none()).hasValue() // false — body collapsed it
328
337
  ```
329
- Together with `optional.of` this is a lawful monad. A plain map (`fmap`) is the
330
- derived form `o.flatMap(v, optional.of(f(v)))`.
338
+ Together with `optional.of`, `flatMap` is a lawful monad and `map` its derived
339
+ Functor (`o.map(v, body)` == `o.flatMap(v, optional.of(body))`).
331
340
 
332
341
  ## Macros
333
342
 
@@ -7,27 +7,79 @@ function assertIdentifier(node, message) {
7
7
  if (node.op === "id") return node.args;
8
8
  throw parseError("invalid_macro_argument", message, node);
9
9
  }
10
+ function buildMapComprehension(callAst, receiver, iterVar, predicate, transform, invalidMsg, label) {
11
+ let step = transform.clone(OPS.accuPush, transform);
12
+ if (predicate) {
13
+ const accuValue = predicate.clone(OPS.accuValue, void 0);
14
+ step = predicate.clone(OPS.ternary, [predicate.setMeta("label", label), step, accuValue]);
15
+ }
16
+ return callAst.clone(OPS.comprehension, {
17
+ errorsAreFatal: true,
18
+ iterable: receiver,
19
+ iterVarName: assertIdentifier(iterVar, invalidMsg),
20
+ init: callAst.clone(OPS.list, []),
21
+ step,
22
+ result: identity
23
+ });
24
+ }
10
25
  function createMapExpander(hasFilter) {
11
26
  const functionDesc = hasFilter ? "map(var, filter, transform)" : "map(var, transform)";
12
27
  const invalidMsg = `${functionDesc} invalid predicate iteration variable`;
13
28
  const label = `${functionDesc} filter predicate must return bool`;
29
+ if (hasFilter) {
30
+ return (opts) => {
31
+ const { args, receiver, ast: callAst } = opts;
32
+ return { callAst: buildMapComprehension(callAst, receiver, args[0], args[1], args[2], invalidMsg, label) };
33
+ };
34
+ }
35
+ function functorMap(ev, macro, ctx, recv) {
36
+ return Effect.gen(function* () {
37
+ if (Option.isNone(recv)) return Option.none();
38
+ const iterCtx = macro.iterCtx.reuse(ctx);
39
+ const result = yield* ev.eval(macro.body, iterCtx.setIterValue(recv.value, ev));
40
+ return Option.some(result);
41
+ });
42
+ }
43
+ function typeCheck(chk, macro, ctx) {
44
+ const recvType = chk.check(macro.receiver, ctx);
45
+ if (recvType.kind === "optional") {
46
+ macro.mode = "optional";
47
+ const innerType = recvType.valueType ?? chk.getType("dyn");
48
+ macro.iterCtx = ctx.forkWithVariable(macro.iterVarName, innerType);
49
+ const bodyType = chk.check(macro.body, macro.iterCtx);
50
+ return chk.registry.getOptionalType(bodyType);
51
+ }
52
+ if (recvType.kind === "dyn") {
53
+ macro.mode = "dyn";
54
+ macro.iterCtx = ctx.forkWithVariable(macro.iterVarName, chk.getType("dyn"));
55
+ chk.check(macro.comprehension, ctx);
56
+ return chk.getType("dyn");
57
+ }
58
+ macro.mode = "list";
59
+ return chk.check(macro.comprehension, ctx);
60
+ }
61
+ function evaluate(ev, macro, ctx) {
62
+ if (macro.mode === "list") return ev.eval(macro.comprehension, ctx);
63
+ if (macro.mode === "optional") {
64
+ return Effect.flatMap(ev.eval(macro.receiver, ctx), (recv) => functorMap(ev, macro, ctx, recv));
65
+ }
66
+ return Effect.flatMap(
67
+ ev.eval(macro.receiver, ctx),
68
+ (recv) => Option.isOption(recv) ? functorMap(ev, macro, ctx, recv) : ev.eval(macro.comprehension, ctx)
69
+ );
70
+ }
14
71
  return (opts) => {
15
72
  const { args, receiver, ast: callAst } = opts;
16
- const [iterVar, predicate, transform] = hasFilter ? args : [args[0], null, args[1]];
17
- let step = transform.clone(OPS.accuPush, transform);
18
- if (predicate) {
19
- const accuValue = predicate.clone(OPS.accuValue, void 0);
20
- step = predicate.clone(OPS.ternary, [predicate.setMeta("label", label), step, accuValue]);
21
- }
22
73
  return {
23
- callAst: callAst.clone(OPS.comprehension, {
24
- errorsAreFatal: true,
25
- iterable: receiver,
26
- iterVarName: assertIdentifier(iterVar, invalidMsg),
27
- init: callAst.clone(OPS.list, []),
28
- step,
29
- result: identity
30
- })
74
+ ast: callAst,
75
+ receiver,
76
+ iterVarName: assertIdentifier(args[0], invalidMsg),
77
+ body: args[1],
78
+ comprehension: buildMapComprehension(callAst, receiver, args[0], null, args[1], invalidMsg, label),
79
+ iterCtx: void 0,
80
+ mode: "list",
81
+ typeCheck,
82
+ evaluate
31
83
  };
32
84
  };
33
85
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shwfed/config",
3
- "version": "2.7.7",
3
+ "version": "2.8.0",
4
4
  "description": "Configurable UI for SHWFED",
5
5
  "type": "module",
6
6
  "publishConfig": {
@@ -1 +0,0 @@
1
- import{b2 as e}from"./index-CHzOsSTW.js";import{b3 as f,b4 as r,b5 as s}from"./index-CHzOsSTW.js";export{f as TableConfig,r as createTableConfig,e as default,s as getColumnTechnicalKey};