@shwfed/config 2.7.6 → 2.7.8

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 (111) hide show
  1. package/dist/mcp.mjs +165 -52
  2. package/dist/module.json +1 -1
  3. package/dist/preview/assets/badge-KAEXz3VO.js +1 -0
  4. package/dist/preview/assets/{config-C947O8za.js → config-BXx5syNf.js} +1 -1
  5. package/dist/preview/assets/{config-DhAntnE5.js → config-Bb9Yeh33.js} +1 -1
  6. package/dist/preview/assets/config-C-QRPeN1.js +1 -0
  7. package/dist/preview/assets/config-CkKx7sVR.js +1 -0
  8. package/dist/preview/assets/config-CtbYlZCL.js +1 -0
  9. package/dist/preview/assets/{config-Bl8L6943.js → config-DPlbFBRi.js} +1 -1
  10. package/dist/preview/assets/config-DbfJWa8K.js +1 -0
  11. package/dist/preview/assets/{config-DppExb4h.js → config-DbirfZyy.js} +1 -1
  12. package/dist/preview/assets/{config-B7hXY5FF.js → config-ZczGik30.js} +1 -1
  13. package/dist/preview/assets/definition.vue_vue_type_script_setup_true_lang-CQ6MUPKO.js +1 -0
  14. package/dist/preview/assets/{index-DiC1rvCq.js → index-Bv_aA34a.js} +1 -1
  15. package/dist/preview/assets/{index-B0PL01fm.css → index-C9P-6gZd.css} +1 -1
  16. package/dist/preview/assets/index-CJFU9znN.js +1 -0
  17. package/dist/preview/assets/index-DUOkekYu.js +680 -0
  18. package/dist/preview/assets/item-SC0WQMVu.js +1 -0
  19. package/dist/preview/assets/{runtime-DmV_M4B_.js → runtime-BPOf7Yqz.js} +1 -1
  20. package/dist/preview/assets/runtime-CC2caFS9.js +1 -0
  21. package/dist/preview/assets/runtime-CLaRFZzt.js +1 -0
  22. package/dist/preview/assets/runtime-Ckuz5Kxm.js +1 -0
  23. package/dist/preview/assets/{runtime-BQnHKogz.js → runtime-CnKlH0mi.js} +1 -1
  24. package/dist/preview/assets/runtime-DO0anKbw.js +1 -0
  25. package/dist/preview/assets/{runtime-kLWO8JbC.js → runtime-DcStOiOi.js} +1 -1
  26. package/dist/preview/assets/runtime-EVgYW6_7.js +1 -0
  27. package/dist/preview/assets/runtime-i32sR7d3.js +1 -0
  28. package/dist/preview/index.html +2 -2
  29. package/dist/runtime/components/actions/buttons/2026-04-21/com.shwfed.actions.button.navigation/runtime.vue +16 -2
  30. package/dist/runtime/components/block-layout-editor/index.vue +1 -4
  31. package/dist/runtime/components/config/blocks/2026-05-17/com.shwfed.block.chart.xy/config.vue +5 -0
  32. package/dist/runtime/components/config/blocks/2026-05-17/com.shwfed.block.chart.xy/runtime.vue +2 -2
  33. package/dist/runtime/components/config/blocks/2026-06-01/com.shwfed.block.animated.number/item.vue +2 -2
  34. package/dist/runtime/components/config/blocks/2026-06-01/com.shwfed.block.animated.number/schema.js +2 -2
  35. package/dist/runtime/components/config/blocks/2026-06-02/com.shwfed.block.card/badge.vue +3 -2
  36. package/dist/runtime/components/config/blocks/2026-06-02/com.shwfed.block.card/schema.js +2 -2
  37. package/dist/runtime/components/form/config.vue +24 -16
  38. package/dist/runtime/components/form/fields/2026-05-13/com.shwfed.form.field.combobox.single.remote/runtime.vue +6 -5
  39. package/dist/runtime/components/form/fields/2026-05-13/com.shwfed.form.field.combobox.single.remote/schema.js +2 -2
  40. package/dist/runtime/components/form/fields/2026-05-23/com.shwfed.form.field.tree.multi/runtime.vue +3 -4
  41. package/dist/runtime/components/form/fields/2026-05-26/com.shwfed.form.field.tree.combobox.multi/runtime.vue +3 -4
  42. package/dist/runtime/components/form/fields/2026-05-26/com.shwfed.form.field.tree.combobox.single/runtime.vue +3 -4
  43. package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.combobox.multi/runtime.vue +6 -5
  44. package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.combobox.multi/schema.js +2 -2
  45. package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.combobox.single/runtime.vue +6 -5
  46. package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.combobox.single/schema.js +2 -2
  47. package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.tree.combobox.multi/runtime.vue +3 -4
  48. package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.tree.combobox.single/runtime.vue +3 -4
  49. package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.tree.multi/runtime.vue +3 -4
  50. package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.tree.single/runtime.vue +3 -4
  51. package/dist/runtime/components/form/schema.d.ts +1 -1
  52. package/dist/runtime/components/form/schema.js +8 -3
  53. package/dist/runtime/components/form/utils/initial.d.ts +5 -4
  54. package/dist/runtime/components/form/utils/initial.js +2 -2
  55. package/dist/runtime/components/form/utils/schema-meta.d.ts +2 -0
  56. package/dist/runtime/components/form/utils/schema-meta.js +24 -0
  57. package/dist/runtime/components/table/columns/2026-05-24/com.shwfed.table.column.combobox-single.remote.options-remote/runtime.vue +7 -6
  58. package/dist/runtime/components/table/columns/2026-05-24/com.shwfed.table.column.combobox-single.remote.options-remote/schema.js +2 -2
  59. package/dist/runtime/components/table/columns/2026-05-25/com.shwfed.table.column.combobox-multi.remote.options-remote/runtime.vue +7 -6
  60. package/dist/runtime/components/table/columns/2026-05-25/com.shwfed.table.column.combobox-multi.remote.options-remote/schema.js +2 -2
  61. package/dist/runtime/components/table/columns/2026-05-26/com.shwfed.table.column.combobox-multi/runtime.vue +7 -6
  62. package/dist/runtime/components/table/columns/2026-05-26/com.shwfed.table.column.combobox-multi/schema.js +2 -2
  63. package/dist/runtime/components/table/columns/2026-05-26/com.shwfed.table.column.combobox-multi.remote/runtime.vue +7 -6
  64. package/dist/runtime/components/table/columns/2026-05-26/com.shwfed.table.column.combobox-multi.remote/schema.js +2 -2
  65. package/dist/runtime/components/table/columns/2026-05-26/com.shwfed.table.column.combobox-single/runtime.vue +7 -6
  66. package/dist/runtime/components/table/columns/2026-05-26/com.shwfed.table.column.combobox-single/schema.js +2 -2
  67. package/dist/runtime/components/table/columns/2026-05-26/com.shwfed.table.column.combobox-single.remote/runtime.vue +7 -6
  68. package/dist/runtime/components/table/columns/2026-05-26/com.shwfed.table.column.combobox-single.remote/schema.js +2 -2
  69. package/dist/runtime/components/table/columns/2026-05-27/com.shwfed.table.column.tree-combobox-multi/runtime.vue +3 -4
  70. package/dist/runtime/components/table/columns/2026-05-27/com.shwfed.table.column.tree-combobox-multi/schema.js +2 -2
  71. package/dist/runtime/components/table/columns/2026-05-27/com.shwfed.table.column.tree-combobox-single/runtime.vue +3 -4
  72. package/dist/runtime/components/table/columns/2026-05-27/com.shwfed.table.column.tree-combobox-single/schema.js +2 -2
  73. package/dist/runtime/components/table/columns/2026-05-28/com.shwfed.table.column.combobox-multi/runtime.vue +7 -6
  74. package/dist/runtime/components/table/columns/2026-05-28/com.shwfed.table.column.combobox-multi/schema.js +2 -2
  75. package/dist/runtime/components/table/columns/2026-05-28/com.shwfed.table.column.combobox-single/runtime.vue +7 -6
  76. package/dist/runtime/components/table/columns/2026-05-28/com.shwfed.table.column.combobox-single/schema.js +2 -2
  77. package/dist/runtime/components/table/columns/2026-05-28/com.shwfed.table.column.tree-combobox-multi/runtime.vue +3 -4
  78. package/dist/runtime/components/table/columns/2026-05-28/com.shwfed.table.column.tree-combobox-multi/schema.js +2 -2
  79. package/dist/runtime/components/table/columns/2026-05-28/com.shwfed.table.column.tree-combobox-single/runtime.vue +3 -4
  80. package/dist/runtime/components/table/columns/2026-05-28/com.shwfed.table.column.tree-combobox-single/schema.js +2 -2
  81. package/dist/runtime/components/table/config.vue +0 -36
  82. package/dist/runtime/components/table/index.vue +3 -4
  83. package/dist/runtime/components/table/schema.js +3 -3
  84. package/dist/runtime/components/ui/expression-editor/ExpressionEditor.d.vue.ts +4 -3
  85. package/dist/runtime/components/ui/expression-editor/ExpressionEditor.vue +135 -111
  86. package/dist/runtime/components/ui/expression-editor/ExpressionEditor.vue.d.ts +4 -3
  87. package/dist/runtime/share/expression.d.ts +36 -0
  88. package/dist/runtime/share/expression.js +38 -17
  89. package/dist/runtime/share/request.d.ts +29 -0
  90. package/dist/runtime/share/request.js +11 -0
  91. package/dist/runtime/vendor/cel-js/CLAUDE.md +3 -3
  92. package/dist/runtime/vendor/cel-js/PROMPT.md +44 -3
  93. package/dist/runtime/vendor/cel-js/lib/functions.js +2 -2
  94. package/dist/runtime/vendor/cel-js/lib/macros.js +66 -14
  95. package/dist/runtime/vendor/cel-js/lib/optional.js +52 -1
  96. package/package.json +1 -1
  97. package/dist/preview/assets/badge-C-IvPZBx.js +0 -1
  98. package/dist/preview/assets/config-DXlCQMVi.js +0 -1
  99. package/dist/preview/assets/config-Dj0rEZRq.js +0 -1
  100. package/dist/preview/assets/config-_aVQvlhc.js +0 -1
  101. package/dist/preview/assets/config-l01zamcS.js +0 -1
  102. package/dist/preview/assets/definition.vue_vue_type_script_setup_true_lang-BbuC0qEM.js +0 -1
  103. package/dist/preview/assets/index-BNaI1T0H.js +0 -680
  104. package/dist/preview/assets/index-BwoBmSxu.js +0 -1
  105. package/dist/preview/assets/item-GFiAkFW6.js +0 -1
  106. package/dist/preview/assets/runtime-5h5U6Ozr.js +0 -1
  107. package/dist/preview/assets/runtime-B6dXW6zW.js +0 -1
  108. package/dist/preview/assets/runtime-BEOIc4zU.js +0 -1
  109. package/dist/preview/assets/runtime-Bx7G-5dR.js +0 -1
  110. package/dist/preview/assets/runtime-TNDFpOlo.js +0 -1
  111. package/dist/preview/assets/runtime-g9hb36Vh.js +0 -1
@@ -2,9 +2,18 @@ import { Either, Schema } from "effect";
2
2
  import { Environment } from "../vendor/cel-js/lib/index.js";
3
3
  import { CelError } from "../vendor/cel-js/lib/errors.js";
4
4
  import { Locale } from "./locale.js";
5
+ export const HttpRequestResult = (t) => t === "HttpRequest" || t === "optional<HttpRequest>" || t === "optional<dyn>" || t === "dyn";
6
+ function matchesScalarType(actual, expected) {
7
+ if (expected === "dyn" || actual === "dyn") return true;
8
+ if (actual === expected) return true;
9
+ if (actual.startsWith(`${expected}<`)) return true;
10
+ if (actual === `optional<${expected}>` || actual === "optional<dyn>") return true;
11
+ if (actual.startsWith(`optional<${expected}<`)) return true;
12
+ return false;
13
+ }
5
14
  function matchesResultType(actual, expected) {
6
- if (typeof expected === "string") return expected === "dyn" || actual === expected;
7
- if (Array.isArray(expected)) return expected.includes("dyn") || expected.includes(actual);
15
+ if (typeof expected === "string") return matchesScalarType(actual, expected);
16
+ if (Array.isArray(expected)) return expected.some((e) => matchesScalarType(actual, e));
8
17
  return expected(actual);
9
18
  }
10
19
  function formatExpectedType(expected) {
@@ -18,6 +27,32 @@ function registerScopeAddressVar(env) {
18
27
  description: "\u6309 UUID \u5BFB\u5740\u88AB\u906E\u853D\u7684\u7956\u5148\u4F5C\u7528\u57DF"
19
28
  });
20
29
  }
30
+ export function evaluateExpression(env, expression, resultType) {
31
+ const result = env.check(expression);
32
+ if (Either.isLeft(result)) {
33
+ const error = result.left;
34
+ const summary = error instanceof CelError ? error.summary : String(error);
35
+ return `\u8868\u8FBE\u5F0F\u65E0\u6548\uFF1A${summary}`;
36
+ }
37
+ if (resultType) {
38
+ const actualType = result.right;
39
+ if (!matchesResultType(actualType, resultType)) {
40
+ return `\u8868\u8FBE\u5F0F\u8FD4\u56DE\u7C7B\u578B\u4E0D\u5339\u914D\uFF0C\u671F\u671B ${formatExpectedType(resultType)}\uFF0C\u5B9E\u9645\u4E3A ${actualType}`;
41
+ }
42
+ }
43
+ return null;
44
+ }
45
+ export function buildCheckEnvironment(vars, options) {
46
+ const env = new Environment({
47
+ unlistedVariablesAreDyn: options?.unlistedVariablesAreDyn ?? false
48
+ });
49
+ registerScopeAddressVar(env);
50
+ for (const { name, type } of vars) {
51
+ if (name === "__scopes__") continue;
52
+ env.registerVariable(name, type);
53
+ }
54
+ return env;
55
+ }
21
56
  function buildDescription(baseline, env, resultType) {
22
57
  const defs = env.getDefinitions();
23
58
  const baselineVarNames = new Set(baseline.variables.map((v) => v.name));
@@ -51,21 +86,7 @@ export function Expression(options) {
51
86
  const description = buildDescription(baseline, env, options.resultType);
52
87
  return Schema.String.pipe(
53
88
  Schema.filter(
54
- (expression) => {
55
- const result = env.check(expression);
56
- if (Either.isLeft(result)) {
57
- const error = result.left;
58
- const summary = error instanceof CelError ? error.summary : String(error);
59
- return `\u8868\u8FBE\u5F0F\u65E0\u6548\uFF1A${summary}`;
60
- }
61
- if (options.resultType) {
62
- const actualType = result.right;
63
- if (!matchesResultType(actualType, options.resultType)) {
64
- return `\u8868\u8FBE\u5F0F\u8FD4\u56DE\u7C7B\u578B\u4E0D\u5339\u914D\uFF0C\u671F\u671B ${formatExpectedType(options.resultType)}\uFF0C\u5B9E\u9645\u4E3A ${actualType}`;
65
- }
66
- }
67
- return true;
68
- },
89
+ (expression) => evaluateExpression(env, expression, options.resultType) ?? true,
69
90
  {
70
91
  title: "CEL Expression",
71
92
  description
@@ -0,0 +1,29 @@
1
+ import { Effect, Option } from 'effect';
2
+ import type { Fetch } from 'fx-fetch';
3
+ import type { HttpRequestBuilder } from '../vendor/cel-js/lib/http-builder.js';
4
+ /**
5
+ * Normalize the value a request expression evaluates to into an
6
+ * `Option<HttpRequestBuilder>`.
7
+ *
8
+ * A request expression now expects `optional<HttpRequest>` — `None` means the
9
+ * author opted out ("no request, skip the fetch"), enabling conditional fetches
10
+ * (e.g. only when a `form_id` is present). For back-compat a bare `HttpRequest`
11
+ * still works (always fetch) and maps to `Some`. A stray `null`/`undefined` is
12
+ * also treated as `None`.
13
+ *
14
+ * We only distinguish *present* from *absent* here — we do NOT `instanceof`-
15
+ * guard the payload. The type-checker already guarantees an `HttpRequest` at
16
+ * this boundary (the `HttpRequestResult` matcher), and a misconfigured non-
17
+ * builder would fail at `.json()`/`.file()` exactly as it did before this
18
+ * contract existed. (Guarding on `instanceof HttpRequestBuilder` would also
19
+ * wrongly reject test doubles that aren't real instances.)
20
+ */
21
+ export declare function asRequest(result: unknown): Option.Option<HttpRequestBuilder>;
22
+ /**
23
+ * Resolve a request expression's value to its JSON response as an `Option`:
24
+ * `Some(body)` when a request was produced and issued, `None` when the
25
+ * expression opted out (or produced no builder). The returned Effect needs a
26
+ * `Fetch` layer. Mirrors the `{ request?, data }` datasource shape, where the
27
+ * response is exposed to the `data` expression as the `json` Option.
28
+ */
29
+ export declare function fetchJsonOption(result: unknown): Effect.Effect<Option.Option<unknown>, unknown, Fetch.Fetch>;
@@ -0,0 +1,11 @@
1
+ import { Effect, Option } from "effect";
2
+ export function asRequest(result) {
3
+ if (Option.isOption(result)) return result;
4
+ return result == null ? Option.none() : Option.some(result);
5
+ }
6
+ export function fetchJsonOption(result) {
7
+ return Option.match(asRequest(result), {
8
+ onNone: () => Effect.succeed(Option.none()),
9
+ onSome: (builder) => Effect.map(builder.json(), Option.some)
10
+ });
11
+ }
@@ -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).
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)
@@ -77,7 +77,7 @@ Internal-only (not re-exported from `index.js`): `parse`, standalone `evaluate`/
77
77
 
78
78
  Primitives: `string`, `bool`, `number`, `bytes`, `null_type`, `type`
79
79
  Composites: `list<T>`, `map<K, V>`, `optional<T>`, `dyn`, `message`
80
- Custom: `Date` (backed by `TZDate` from `@date-fns/tz`), `URL` (backed by the native `URL`; method `URL.param(string): string` reads a search param), `File` (native), `FormData` (native — see `form-builtins.ts`), `http` / `HttpRequest` (local addition — see `http-builtins.ts`)
80
+ Custom: `Date` (backed by `TZDate` from `@date-fns/tz`), `URL` (backed by the native `URL`; method `URL.query(string): optional<string>` reads a search param — `None` when absent, distinguishing it from a present-but-empty value), `File` (native), `FormData` (native — see `form-builtins.ts`), `http` / `HttpRequest` (local addition — see `http-builtins.ts`)
81
81
 
82
82
  ## Function Signature Format
83
83
 
@@ -242,10 +242,13 @@ range(date("2024-01-01"), date("2024-04-01"), "month")
242
242
  ### URL
243
243
  A `URL` value is supplied by the host (e.g. a `location` variable bound to the
244
244
  current page URL). You cannot construct one in CEL.
245
+ `query(name)` returns `optional<string>` — `Some(value)` when the param is
246
+ present (including a present-but-empty value), `None` when it is absent. Unwrap
247
+ it with `.orValue(...)` / `.hasValue()` / `.value()`.
245
248
  ```cel
246
- location.param("tab") // value of the ?tab= search param
247
- location.param("missing") // "" — absent params yield empty string
248
- location.param("id") // first value when a param repeats
249
+ location.query("tab").orValue("") // value of the ?tab= search param, "" if absent
250
+ location.query("missing").hasValue() // false — absent params are None
251
+ location.query("id").orValue("") // first value when a param repeats
249
252
  ```
250
253
 
251
254
  ## HTTP
@@ -297,6 +300,44 @@ http.post("https://api.example.com/users")
297
300
  .body({"name": "Alice"})
298
301
  ```
299
302
 
303
+ ## Optionals
304
+
305
+ An `optional<T>` is either present (`Some`) or absent (`None`). They come from
306
+ `.?` / `[?]` access, `find`, and `URL.query`. Build them with `optional.of(x)`
307
+ (the lift — wraps a value as present) and `optional.none()`.
308
+
309
+ ```cel
310
+ optional.of(5) // present, holds 5
311
+ optional.none() // absent
312
+
313
+ o.hasValue() // bool — is it present?
314
+ o.value() // unwrap — ERRORS if absent
315
+ o.orValue(default) // unwrap, or `default` when absent
316
+ o.or(otherOptional) // first present optional wins
317
+ ```
318
+
319
+ ### map — transform 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
+ short-circuits to `None` and `body` is never evaluated.
323
+ ```cel
324
+ loc.query("id").map(v, "user-" + v).orValue("anon")
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
335
+
336
+ optional.of(2).flatMap(v, optional.none()).hasValue() // false — body collapsed it
337
+ ```
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))`).
340
+
300
341
  ## Macros
301
342
 
302
343
  Macros are special forms — they look like method calls but have special evaluation semantics.
@@ -1,7 +1,7 @@
1
1
  import { evaluationError } from "./errors.js";
2
2
  import { Decimal } from "./decimal.js";
3
3
  import { TYPES, Type } from "./registry.js";
4
- import { register as registerOptional } from "./optional.js";
4
+ import { register as registerOptional, optionalOf } from "./optional.js";
5
5
  import { objKeys, arrayFrom } from "./globals.js";
6
6
  import { TZDate } from "@date-fns/tz";
7
7
  import { startOfDay, startOfWeek, startOfMonth, startOfYear, endOfDay, endOfWeek, endOfMonth, endOfYear, addDays, addWeeks, addMonths, addYears, addHours, addMinutes, setDate as setDayOfMonth, setMonth, setYear, format as formatDate } from "date-fns";
@@ -392,7 +392,7 @@ export function registerFunctions(registry) {
392
392
  functionOverload("Date.format(string): string", (d, fmt) => formatDate(d, fmt));
393
393
  registry.registerType("File", File);
394
394
  registry.registerType("URL", URL);
395
- functionOverload("URL.param(string): string", (url, key) => url.searchParams.get(key) ?? "");
395
+ functionOverload("URL.query(string): optional<string>", (url, key) => optionalOf(url.searchParams.get(key) ?? void 0));
396
396
  registerOptional(registry);
397
397
  }
398
398
  function stringSize(str) {
@@ -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
  }
@@ -1,5 +1,5 @@
1
1
  import { Effect, Option } from "effect";
2
- import { evaluationError } from "./errors.js";
2
+ import { evaluationError, parseError } from "./errors.js";
3
3
  export function optionalOf(value) {
4
4
  return value === void 0 ? Option.none() : Option.some(value);
5
5
  }
@@ -108,4 +108,55 @@ export function register(registry) {
108
108
  }
109
109
  })
110
110
  );
111
+ registry.registerFunctionOverload(
112
+ "optional<A>.flatMap(ast, ast): optional<dyn>",
113
+ createFlatMapExpander()
114
+ );
115
+ }
116
+ function createFlatMapExpander() {
117
+ const functionDesc = "optional.flatMap(var, body)";
118
+ const invalidVar = `${functionDesc} invalid iteration variable`;
119
+ const invalidReceiver = `${functionDesc} receiver`;
120
+ const invalidBody = `${functionDesc} body`;
121
+ function ensureOptional(value, ast, description) {
122
+ if (Option.isOption(value)) return value;
123
+ throw evaluationError("optional_expected", `${description} must be optional`, ast);
124
+ }
125
+ function ensureOptionalType(checker, node, ctx, description) {
126
+ const type = checker.check(node, ctx);
127
+ if (type.kind === "optional") return type;
128
+ if (type.kind === "dyn") return checker.getType("optional");
129
+ throw checker.createError("optional_expected", `${description} must be optional, got '${type}'`, node);
130
+ }
131
+ function typeCheck(checker, macro, ctx) {
132
+ const receiverType = ensureOptionalType(checker, macro.receiver, ctx, invalidReceiver);
133
+ const innerType = receiverType.valueType ?? checker.getType("dyn");
134
+ macro.iterCtx = ctx.forkWithVariable(macro.iterVarName, innerType);
135
+ return ensureOptionalType(checker, macro.body, macro.iterCtx, invalidBody);
136
+ }
137
+ function evaluate(ev, macro, ctx) {
138
+ return Effect.gen(function* () {
139
+ const recv = yield* ev.eval(macro.receiver, ctx);
140
+ const optional = ensureOptional(recv, macro.receiver, invalidReceiver);
141
+ if (Option.isNone(optional)) return Option.none();
142
+ const iterCtx = macro.iterCtx.reuse(ctx);
143
+ const result = yield* ev.eval(macro.body, iterCtx.setIterValue(optional.value, ev));
144
+ return ensureOptional(result, macro.body, invalidBody);
145
+ });
146
+ }
147
+ return (opts) => {
148
+ const { args, receiver, ast } = opts;
149
+ const iterVar = args[0];
150
+ if (iterVar.op !== "id") throw parseError("invalid_macro_argument", invalidVar, iterVar);
151
+ return {
152
+ ast,
153
+ receiver,
154
+ functionDesc,
155
+ iterVarName: iterVar.args,
156
+ body: args[1],
157
+ iterCtx: void 0,
158
+ evaluate,
159
+ typeCheck
160
+ };
161
+ };
111
162
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shwfed/config",
3
- "version": "2.7.6",
3
+ "version": "2.7.8",
4
4
  "description": "Configurable UI for SHWFED",
5
5
  "type": "module",
6
6
  "publishConfig": {
@@ -1 +0,0 @@
1
- import{d as M,F,u as $,o as z,w as p,a as v,y as E,c as w,z as x,b as f,_ as y,G as I,H as L,I as N,J as P,K as S,e as t,g as V,f as m,i as A,p as G,l as H,j as J,r as K,k as O,q as T,L as W,M as D,t as Q,m as R,s as U}from"./index-BNaI1T0H.js";const Y=M({name:"ShwfedBlockCardBadge",inheritAttrs:!1,__name:"badge",props:{badge:{}},setup(n){const a=n,{locale:k}=F(),j=T(),o=K(void 0);function i(){return O(j)}const g=t(()=>o.value===void 0?R():U(o.value)),l=t(()=>W(a.badge.content,k.value)||""),C=t(()=>l.value?D(l.value,m,{...i(),json:g.value}):""),B=t(()=>{const e=a.badge.show;if(!e)return!0;try{return Q(m(e,{...i(),json:g.value}))}catch(r){return console.warn("[shwfed-card-badge] show evaluation failed",r),!0}});async function s(){const e=a.badge.request;if(!e)return;const r=i(),q=V(function*(){return yield*(yield*m(e,r)).json()});try{o.value=await A(G(q,H))}catch(h){console.warn("[shwfed-card-badge] fetch failed",h)}}const u=t(()=>!!a.badge.request&&(a.badge.interval??0)>0),_=t(()=>Math.max(1,a.badge.interval??1)*1e3),c=J(),{pause:b,resume:d}=$(()=>{s()},_,{immediate:!1});return z(()=>{s(),u.value&&c.value&&d()}),p(c,e=>{u.value&&(e?(s(),d()):b())}),p(()=>[a.badge.request??"",a.badge.interval??0].join("|"),()=>{s(),u.value&&c.value?d():b()}),(e,r)=>l.value&&B.value?(v(),E(P,{key:0},[n.badge.dot?(v(),w(f(y),x({key:0,variant:n.badge.variant??"default",class:"size-2.5 min-w-0 rounded-full p-0"},e.$attrs),null,16,["variant"])):(v(),w(f(y),x({key:1,variant:n.badge.variant??"default"},e.$attrs),{default:I(()=>[L(f(N),{source:C.value,class:"max-w-none text-inherit [&_*]:text-inherit [&_p]:m-0"},null,8,["source"])]),_:1},16,["variant"]))],64)):S("",!0)}});export{Y as default};
@@ -1 +0,0 @@
1
- import{d as z,a as y,y as E,v as V,N as T,b as e,O as U,P as $,Q as j,c as F,G as l,R as v,H as s,S as d,T as u,U as p,V as m,W as f,I as g,X as b,Y as N,Z as h,$ as B,J as C,a0 as H,a1 as O,a2 as R,a3 as D}from"./index-BNaI1T0H.js";const P=z({__name:"FieldGroup",props:{class:{type:[Boolean,null,String,Object,Array]}},setup(_){const r=_;return(x,i)=>(y(),E("div",{"data-slot":"field-group",class:T(e(U)("group/field-group @container/field-group flex w-full flex-col gap-7 data-[slot=checkbox-group]:gap-3 *:data-[slot=field-group]:gap-4",r.class))},[V(x.$slots,"default")],2))}}),q={class:"grid grid-cols-2 gap-4"},I={class:"grid grid-cols-2 gap-4"},J={class:"flex items-start gap-2"},L={class:"grid grid-cols-2 gap-3"},G=z({name:"ShwfedHttpRequestConfirmActionConfig",__name:"config",props:{modelValue:{required:!0},modelModifiers:{}},emits:["update:modelValue"],setup(_){const r=$(_,"modelValue"),x=j(()=>{}),i=n=>R(x,n)??n,a=n=>D(x,n);function c(n){const t={...r.value,...n};for(const[o,k]of Object.entries(n))k===void 0&&Reflect.deleteProperty(t,o);r.value=t}const S=["onSuccess","onWarning","onError","onInfo"];function w(n,t){c({[n]:t.length===0?void 0:t})}return(n,t)=>(y(),F(e(P),null,{default:l(()=>[v("div",q,[s(e(d),{orientation:"vertical"},{default:l(()=>[s(e(u),{class:"text-xs text-zinc-500"},p({default:l(()=>[m(" "+f(i("expression")),1)]),_:2},[a("expression")?{name:"tooltip",fn:l(()=>[s(e(g),{source:a("expression"),block:"",class:"prose prose-sm prose-zinc"},null,8,["source"])]),key:"0"}:void 0]),1024),s(e(b),{"model-value":r.value.expression,multiline:"",placeholder:"例:http.post('/api/foo').body({ id: row.id })","result-type":"HttpRequest",class:"min-h-16","onUpdate:modelValue":t[0]||(t[0]=o=>c({expression:o}))},null,8,["model-value"])]),_:1}),s(e(d),{orientation:"vertical"},{default:l(()=>[s(e(u),{class:"text-xs text-zinc-500"},p({default:l(()=>[m(" "+f(i("markdown")),1)]),_:2},[a("markdown")?{name:"tooltip",fn:l(()=>[s(e(g),{source:a("markdown"),block:"",class:"prose prose-sm prose-zinc"},null,8,["source"])]),key:"0"}:void 0]),1024),s(e(N),{markdown:"","model-value":r.value.markdown,"onUpdate:modelValue":t[1]||(t[1]=o=>c({markdown:o}))},null,8,["model-value"])]),_:1})]),v("div",I,[s(e(d),{orientation:"vertical"},{default:l(()=>[s(e(u),{class:"text-xs text-zinc-500"},p({default:l(()=>[m(" "+f(i("icon")),1)]),_:2},[a("icon")?{name:"tooltip",fn:l(()=>[s(e(g),{source:a("icon"),block:"",class:"prose prose-sm prose-zinc"},null,8,["source"])]),key:"0"}:void 0]),1024),s(e(h),{"model-value":r.value.icon??"","onUpdate:modelValue":t[2]||(t[2]=o=>c(o.trim()===""?{icon:void 0}:{icon:o}))},null,8,["model-value"])]),_:1}),s(e(d),{orientation:"vertical"},{default:l(()=>[s(e(u),{class:"text-xs text-zinc-500"},p({default:l(()=>[m(" "+f(i("color")),1)]),_:2},[a("color")?{name:"tooltip",fn:l(()=>[s(e(g),{source:a("color"),block:"",class:"prose prose-sm prose-zinc"},null,8,["source"])]),key:"0"}:void 0]),1024),s(e(B),{"model-value":r.value.color??"","onUpdate:modelValue":t[3]||(t[3]=o=>c(o.trim()===""?{color:void 0}:{color:o}))},null,8,["model-value"])]),_:1})]),v("div",J,[s(e(d),{orientation:"vertical",class:"flex-1 basis-0 min-w-0"},{default:l(()=>[s(e(u),{class:"text-xs text-zinc-500"},p({default:l(()=>[m(" "+f(i("messageExpression")),1)]),_:2},[a("messageExpression")?{name:"tooltip",fn:l(()=>[s(e(g),{source:a("messageExpression"),block:"",class:"prose prose-sm prose-zinc"},null,8,["source"])]),key:"0"}:void 0]),1024),s(e(b),{"model-value":r.value.messageExpression??"",placeholder:"例:string(json.message)","result-type":"string","extra-vars":{json:{type:"dyn",label:"HTTP 响应体(已解析 JSON)"}},"onUpdate:modelValue":t[4]||(t[4]=o=>c({messageExpression:o===""?void 0:o}))},null,8,["model-value"])]),_:1}),s(e(d),{orientation:"vertical",class:"flex-1 basis-0 min-w-0"},{default:l(()=>[s(e(u),{class:"text-xs text-zinc-500"},p({default:l(()=>[m(" "+f(i("resultExpression")),1)]),_:2},[a("resultExpression")?{name:"tooltip",fn:l(()=>[s(e(g),{source:a("resultExpression"),block:"",class:"prose prose-sm prose-zinc"},null,8,["source"])]),key:"0"}:void 0]),1024),s(e(b),{"model-value":r.value.resultExpression??"",placeholder:"例:json.code == 0 ? 'success' : 'error'","result-type":"string","extra-vars":{json:{type:"dyn",label:"HTTP 响应体(已解析 JSON)"}},"onUpdate:modelValue":t[5]||(t[5]=o=>c({resultExpression:o===""?void 0:o}))},null,8,["model-value"])]),_:1})]),v("div",L,[(y(),E(C,null,H(S,o=>s(e(d),{key:o,orientation:"vertical",class:"min-w-0"},{default:l(()=>[s(e(u),{class:"text-xs text-zinc-500"},p({default:l(()=>[m(" "+f(i(o)),1)]),_:2},[a(o)?{name:"tooltip",fn:l(()=>[s(e(g),{source:a(o),block:"",class:"prose prose-sm prose-zinc"},null,8,["source"])]),key:"0"}:void 0]),1024),s(O,{triggers:r.value[o]??[],"onUpdate:triggers":k=>w(o,k)},null,8,["triggers","onUpdate:triggers"])]),_:2},1024)),64))])]),_:1}))}});export{G as default};
@@ -1 +0,0 @@
1
- import{d as g,P as d,a2 as u,az as f,y as m,H as s,G as i,b as r,a as p,T as _,V as v,W as x,a1 as h,S as T,e as V}from"./index-BNaI1T0H.js";const S={class:"flex flex-col gap-3"},C=g({name:"ShwfedEventDispatchActionConfig",__name:"config",props:{modelValue:{required:!0},modelModifiers:{}},emits:["update:modelValue"],setup(l){const t=d(l,"modelValue"),o=u(f(),"triggers")??"触发的操作",n=V(()=>t.value.triggers??[]);function c(a){const e={...t.value};a.length===0?Reflect.deleteProperty(e,"triggers"):e.triggers=a,t.value=e}return(a,e)=>(p(),m("div",S,[s(r(T),{orientation:"vertical"},{default:i(()=>[s(r(_),{class:"text-xs text-zinc-500"},{default:i(()=>[v(x(r(o)),1)]),_:1}),s(h,{triggers:n.value,"onUpdate:triggers":c},null,8,["triggers"])]),_:1})]))}});export{C as default};
@@ -1 +0,0 @@
1
- import{d as _,P as y,a5 as x,a6 as b,y as c,R as i,H as n,G as o,b as t,a as l,a7 as v,a8 as u,a9 as g,aa as D,J as h,a0 as S,c as $,ab as k,W as p,ac as w}from"./index-BNaI1T0H.js";const B={class:"flex flex-col gap-3"},C={class:"flex-1"},V={class:"ml-auto text-xs tabular-nums text-zinc-400"},N=_({name:"ShwfedPrototypeActionConfig",__name:"config",props:{modelValue:{required:!0},modelModifiers:{}},emits:["update:modelValue"],setup(m){const r=y(m,"modelValue"),f=(()=>{const s=new Map;for(const e of x){if(e.type===b||e.deprecated)continue;const a=s.get(e.type);(!a||e.compatibilityDate>a.compatibilityDate)&&s.set(e.type,{type:e.type,compatibilityDate:e.compatibilityDate,name:e.metadata.name,icon:e.metadata.icon})}return[...s.values()].sort((e,a)=>e.name.localeCompare(a.name,"zh"))})();function d(s,e){r.value={type:s,compatibilityDate:e}}return(s,e)=>(l(),c("div",B,[e[0]||(e[0]=i("p",{class:"text-xs text-zinc-500"}," 原型按钮点击后无任何副作用,用于占位。选择下方任意类型可将其转换为正式按钮 —— 此转换仅能进行一次。 ",-1)),n(t(w),null,{default:o(()=>[n(t(v),{align:"inline-start"},{default:o(()=>[n(t(u),{icon:"fluent:arrow-swap-20-regular"})]),_:1}),n(t(g),null,{default:o(()=>[n(t(D),null,{default:o(()=>[(l(!0),c(h,null,S(t(f),a=>(l(),$(t(k),{key:a.type,value:a.type,onSelect:z=>d(a.type,a.compatibilityDate)},{default:o(()=>[n(t(u),{icon:a.icon,class:"size-4 shrink-0"},null,8,["icon"]),i("span",C,p(a.name),1),i("span",V,p(a.compatibilityDate),1)]),_:2},1032,["value","onSelect"]))),128))]),_:1})]),_:1})]),_:1})]))}});export{N as default};
@@ -1 +0,0 @@
1
- import{d as x,P as k,b0 as S,y as V,H as e,G as l,b as a,a as g,T as r,U as m,V as d,W as f,I as p,au as $,S as _,Y as b,a2 as w,a3 as y}from"./index-BNaI1T0H.js";const z={class:"flex flex-col gap-4"},h=x({name:"ShwfedMarkdownItemConfig",__name:"config",props:{modelValue:{required:!0},modelModifiers:{}},emits:["update:modelValue"],setup(v){const t=k(v,"modelValue"),c=S(),u=o=>w(c,o)??o,s=o=>y(c,o);return(o,n)=>(g(),V("div",z,[e(a(_),{orientation:"vertical"},{default:l(()=>[e(a(r),{class:"text-xs text-zinc-500"},m({default:l(()=>[d(" "+f(u("name")),1)]),_:2},[s("name")?{name:"tooltip",fn:l(()=>[e(a(p),{source:s("name"),block:"",class:"prose prose-sm prose-zinc"},null,8,["source"])]),key:"0"}:void 0]),1024),e(a($),{"model-value":t.value.name,placeholder:"仅用于编辑器内识别","onUpdate:modelValue":n[0]||(n[0]=i=>t.value={...t.value,name:String(i)})},null,8,["model-value"])]),_:1}),e(a(_),{orientation:"vertical"},{default:l(()=>[e(a(r),{class:"text-xs text-zinc-500"},m({default:l(()=>[d(" "+f(u("content")),1)]),_:2},[s("content")?{name:"tooltip",fn:l(()=>[e(a(p),{source:s("content"),block:"",class:"prose prose-sm prose-zinc"},null,8,["source"])]),key:"0"}:void 0]),1024),e(a(b),{markdown:"",multiline:"","model-value":t.value.content,"onUpdate:modelValue":n[1]||(n[1]=i=>t.value={...t.value,content:i})},null,8,["model-value"])]),_:1})]))}});export{h as default};
@@ -1 +0,0 @@
1
- import{d as f,aZ as u,o as m,a_ as p,al as g,K as l,x as I,a$ as _}from"./index-BNaI1T0H.js";const w=f({name:"ShwfedActionDefinition",inheritAttrs:!1,__name:"definition",props:{actionId:{},effect:{}},setup(r){const n=r,a=u(),t=I(_,void 0),i=crypto.randomUUID(),c=import.meta.dev;let e,s=!1;function d(){!c||s||(s=!0,console.warn("[shwfed-action-definition] must be used inside <shwfed-actions>."))}function o(){if(!t){d();return}e&&e!==n.actionId&&t.unregisterAction(e,i),t.registerAction({ownerId:i,actionId:n.actionId,effect:n.effect,render:a.default}),e=n.actionId}return o(),m(()=>{o()}),p(()=>{o()}),g(()=>{!t||!e||t.unregisterAction(e,i)}),(y,A)=>l("",!0)}});export{w as _};