@shwfed/config 2.12.0 → 2.12.2
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/dist/module.json +1 -1
- package/dist/module.mjs +10 -0
- package/dist/runtime/components/form/config.vue +17 -6
- package/dist/runtime/components/form/fields/2026-04-24/com.shwfed.form.field.combobox.single/config.d.vue.ts +2 -2
- package/dist/runtime/components/form/fields/2026-04-24/com.shwfed.form.field.combobox.single/config.vue.d.ts +2 -2
- package/dist/runtime/components/form/fields/2026-04-27/com.shwfed.form.field.date/config.d.vue.ts +2 -0
- package/dist/runtime/components/form/fields/2026-04-27/com.shwfed.form.field.date/config.vue +22 -0
- package/dist/runtime/components/form/fields/2026-04-27/com.shwfed.form.field.date/config.vue.d.ts +2 -0
- package/dist/runtime/components/form/fields/2026-04-27/com.shwfed.form.field.date/runtime.vue +5 -0
- package/dist/runtime/components/form/fields/2026-04-27/com.shwfed.form.field.date/schema.d.ts +1 -0
- package/dist/runtime/components/form/fields/2026-04-27/com.shwfed.form.field.date/schema.js +12 -0
- package/dist/runtime/components/form/fields/2026-04-27/com.shwfed.form.field.daterange/config.d.vue.ts +2 -0
- package/dist/runtime/components/form/fields/2026-04-27/com.shwfed.form.field.daterange/config.vue +22 -0
- package/dist/runtime/components/form/fields/2026-04-27/com.shwfed.form.field.daterange/config.vue.d.ts +2 -0
- package/dist/runtime/components/form/fields/2026-04-27/com.shwfed.form.field.daterange/runtime.vue +5 -0
- package/dist/runtime/components/form/fields/2026-04-27/com.shwfed.form.field.daterange/schema.d.ts +1 -0
- package/dist/runtime/components/form/fields/2026-04-27/com.shwfed.form.field.daterange/schema.js +12 -0
- package/dist/runtime/components/form/fields/2026-04-27/com.shwfed.form.field.datetime/config.d.vue.ts +2 -0
- package/dist/runtime/components/form/fields/2026-04-27/com.shwfed.form.field.datetime/config.vue +22 -0
- package/dist/runtime/components/form/fields/2026-04-27/com.shwfed.form.field.datetime/config.vue.d.ts +2 -0
- package/dist/runtime/components/form/fields/2026-04-27/com.shwfed.form.field.datetime/runtime.vue +5 -0
- package/dist/runtime/components/form/fields/2026-04-27/com.shwfed.form.field.datetime/schema.d.ts +1 -0
- package/dist/runtime/components/form/fields/2026-04-27/com.shwfed.form.field.datetime/schema.js +12 -0
- package/dist/runtime/components/form/fields/2026-04-27/com.shwfed.form.field.datetimerange/config.d.vue.ts +2 -0
- package/dist/runtime/components/form/fields/2026-04-27/com.shwfed.form.field.datetimerange/config.vue +22 -0
- package/dist/runtime/components/form/fields/2026-04-27/com.shwfed.form.field.datetimerange/config.vue.d.ts +2 -0
- package/dist/runtime/components/form/fields/2026-04-27/com.shwfed.form.field.datetimerange/runtime.vue +5 -0
- package/dist/runtime/components/form/fields/2026-04-27/com.shwfed.form.field.datetimerange/schema.d.ts +1 -0
- package/dist/runtime/components/form/fields/2026-04-27/com.shwfed.form.field.datetimerange/schema.js +12 -0
- package/dist/runtime/components/form/fields/2026-05-13/com.shwfed.form.field.combobox.single.remote/config.d.vue.ts +2 -2
- package/dist/runtime/components/form/fields/2026-05-13/com.shwfed.form.field.combobox.single.remote/config.vue.d.ts +2 -2
- package/dist/runtime/components/form/fields/2026-05-13/com.shwfed.form.field.list/row.vue +8 -1
- package/dist/runtime/components/form/fields/2026-05-23/com.shwfed.form.field.tree.multi/config.d.vue.ts +24 -24
- package/dist/runtime/components/form/fields/2026-05-23/com.shwfed.form.field.tree.multi/config.vue.d.ts +24 -24
- package/dist/runtime/components/form/fields/2026-05-24/com.shwfed.form.field.month/config.d.vue.ts +2 -0
- package/dist/runtime/components/form/fields/2026-05-24/com.shwfed.form.field.month/config.vue +22 -0
- package/dist/runtime/components/form/fields/2026-05-24/com.shwfed.form.field.month/config.vue.d.ts +2 -0
- package/dist/runtime/components/form/fields/2026-05-24/com.shwfed.form.field.month/runtime.vue +5 -0
- package/dist/runtime/components/form/fields/2026-05-24/com.shwfed.form.field.month/schema.d.ts +1 -0
- package/dist/runtime/components/form/fields/2026-05-24/com.shwfed.form.field.month/schema.js +12 -0
- package/dist/runtime/components/form/fields/2026-05-24/com.shwfed.form.field.monthrange/config.d.vue.ts +2 -0
- package/dist/runtime/components/form/fields/2026-05-24/com.shwfed.form.field.monthrange/config.vue +22 -0
- package/dist/runtime/components/form/fields/2026-05-24/com.shwfed.form.field.monthrange/config.vue.d.ts +2 -0
- package/dist/runtime/components/form/fields/2026-05-24/com.shwfed.form.field.monthrange/runtime.vue +5 -0
- package/dist/runtime/components/form/fields/2026-05-24/com.shwfed.form.field.monthrange/schema.d.ts +1 -0
- package/dist/runtime/components/form/fields/2026-05-24/com.shwfed.form.field.monthrange/schema.js +12 -0
- package/dist/runtime/components/form/fields/2026-05-25/com.shwfed.form.field.combobox.multi/config.d.vue.ts +2 -2
- package/dist/runtime/components/form/fields/2026-05-25/com.shwfed.form.field.combobox.multi/config.vue.d.ts +2 -2
- package/dist/runtime/components/form/fields/2026-05-26/com.shwfed.form.field.tree.combobox.multi/config.d.vue.ts +24 -24
- package/dist/runtime/components/form/fields/2026-05-26/com.shwfed.form.field.tree.combobox.multi/config.vue.d.ts +24 -24
- package/dist/runtime/components/form/fields/2026-05-26/com.shwfed.form.field.tree.combobox.single/config.d.vue.ts +22 -22
- package/dist/runtime/components/form/fields/2026-05-26/com.shwfed.form.field.tree.combobox.single/config.vue.d.ts +22 -22
- package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.combobox.multi/config.d.vue.ts +32 -32
- package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.combobox.multi/config.vue.d.ts +32 -32
- package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.combobox.multi/runtime.vue +9 -1
- package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.combobox.single/config.d.vue.ts +32 -32
- package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.combobox.single/config.vue.d.ts +32 -32
- package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.combobox.single/runtime.vue +9 -1
- package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.tree.combobox.multi/config.d.vue.ts +24 -24
- package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.tree.combobox.multi/config.vue.d.ts +24 -24
- package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.tree.combobox.multi/runtime.vue +19 -1
- package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.tree.combobox.single/config.d.vue.ts +22 -22
- package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.tree.combobox.single/config.vue.d.ts +22 -22
- package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.tree.combobox.single/runtime.vue +19 -1
- package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.tree.multi/config.d.vue.ts +24 -24
- package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.tree.multi/config.vue.d.ts +24 -24
- package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.tree.multi/runtime.vue +20 -1
- package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.tree.single/config.d.vue.ts +22 -22
- package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.tree.single/config.vue.d.ts +22 -22
- package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.tree.single/runtime.vue +20 -1
- package/dist/runtime/components/form/fields/2026-06-14/com.shwfed.form.field.combobox.multi/config.d.vue.ts +32 -32
- package/dist/runtime/components/form/fields/2026-06-14/com.shwfed.form.field.combobox.multi/config.vue.d.ts +32 -32
- package/dist/runtime/components/form/fields/2026-06-14/com.shwfed.form.field.combobox.multi/runtime.vue +9 -1
- package/dist/runtime/components/form/fields/2026-06-14/com.shwfed.form.field.combobox.single/config.d.vue.ts +32 -32
- package/dist/runtime/components/form/fields/2026-06-14/com.shwfed.form.field.combobox.single/config.vue.d.ts +32 -32
- package/dist/runtime/components/form/fields/2026-06-14/com.shwfed.form.field.combobox.single/runtime.vue +9 -1
- package/dist/runtime/components/form/index.vue +6 -3
- package/dist/runtime/components/form/utils/ai-field-tools.d.ts +11 -0
- package/dist/runtime/components/form/utils/ai-field-tools.js +282 -0
- package/dist/runtime/components/form/utils/form-vars.js +2 -1
- package/dist/runtime/components/form/utils/resolve.d.ts +15 -0
- package/dist/runtime/components/form/utils/resolve.js +13 -0
- package/dist/runtime/components/head.d.vue.ts +13 -0
- package/dist/runtime/components/head.vue +69 -0
- package/dist/runtime/components/head.vue.d.ts +13 -0
- package/dist/runtime/components/sidebar/config.d.vue.ts +7 -0
- package/dist/runtime/components/sidebar/config.vue +302 -0
- package/dist/runtime/components/sidebar/config.vue.d.ts +7 -0
- package/dist/runtime/components/sidebar/favorites.d.ts +18 -0
- package/dist/runtime/components/sidebar/favorites.js +20 -0
- package/dist/runtime/components/sidebar/footer.d.vue.ts +11 -0
- package/dist/runtime/components/sidebar/footer.vue +49 -0
- package/dist/runtime/components/sidebar/footer.vue.d.ts +11 -0
- package/dist/runtime/components/sidebar/index.d.vue.ts +50 -0
- package/dist/runtime/components/sidebar/index.vue +100 -0
- package/dist/runtime/components/sidebar/index.vue.d.ts +50 -0
- package/dist/runtime/components/sidebar/node.d.vue.ts +9 -0
- package/dist/runtime/components/sidebar/node.vue +102 -0
- package/dist/runtime/components/sidebar/node.vue.d.ts +9 -0
- package/dist/runtime/components/sidebar/schema.d.ts +72 -0
- package/dist/runtime/components/sidebar/schema.js +84 -0
- package/dist/runtime/components/sidebar/tree.d.vue.ts +10 -0
- package/dist/runtime/components/sidebar/tree.vue +260 -0
- package/dist/runtime/components/sidebar/tree.vue.d.ts +10 -0
- package/dist/runtime/components/sidebar/types.d.ts +19 -0
- package/dist/runtime/components/sidebar/types.js +0 -0
- package/dist/runtime/components/sidebar/use-editor.d.ts +18 -0
- package/dist/runtime/components/sidebar/use-editor.js +43 -0
- package/dist/runtime/components/table/ai-generate.system.md +6 -0
- package/dist/runtime/components/table/ai-generate.vue +18 -17
- package/dist/runtime/components/table/columns/2026-05-24/com.shwfed.table.column.combobox-single.remote.options-remote/config.d.vue.ts +4 -4
- package/dist/runtime/components/table/columns/2026-05-24/com.shwfed.table.column.combobox-single.remote.options-remote/config.vue.d.ts +4 -4
- package/dist/runtime/components/table/columns/2026-05-24/com.shwfed.table.column.combobox-single.remote.options-static/config.d.vue.ts +2 -2
- package/dist/runtime/components/table/columns/2026-05-24/com.shwfed.table.column.combobox-single.remote.options-static/config.vue.d.ts +2 -2
- package/dist/runtime/components/table/columns/2026-05-25/com.shwfed.table.column.combobox-multi.remote.options-remote/config.d.vue.ts +4 -4
- package/dist/runtime/components/table/columns/2026-05-25/com.shwfed.table.column.combobox-multi.remote.options-remote/config.vue.d.ts +4 -4
- package/dist/runtime/components/table/columns/2026-05-25/com.shwfed.table.column.combobox-multi.remote.options-static/config.d.vue.ts +2 -2
- package/dist/runtime/components/table/columns/2026-05-25/com.shwfed.table.column.combobox-multi.remote.options-static/config.vue.d.ts +2 -2
- package/dist/runtime/components/table/columns/2026-05-26/com.shwfed.table.column.combobox-multi/config.d.vue.ts +36 -36
- package/dist/runtime/components/table/columns/2026-05-26/com.shwfed.table.column.combobox-multi/config.vue.d.ts +36 -36
- package/dist/runtime/components/table/columns/2026-05-26/com.shwfed.table.column.combobox-multi.remote/config.d.vue.ts +42 -42
- package/dist/runtime/components/table/columns/2026-05-26/com.shwfed.table.column.combobox-multi.remote/config.vue.d.ts +42 -42
- package/dist/runtime/components/table/columns/2026-05-26/com.shwfed.table.column.combobox-single/config.d.vue.ts +36 -36
- package/dist/runtime/components/table/columns/2026-05-26/com.shwfed.table.column.combobox-single/config.vue.d.ts +36 -36
- package/dist/runtime/components/table/columns/2026-05-26/com.shwfed.table.column.combobox-single.remote/config.d.vue.ts +42 -42
- package/dist/runtime/components/table/columns/2026-05-26/com.shwfed.table.column.combobox-single.remote/config.vue.d.ts +42 -42
- package/dist/runtime/components/table/columns/2026-05-27/com.shwfed.table.column.tree-combobox-multi/config.d.vue.ts +4 -4
- package/dist/runtime/components/table/columns/2026-05-27/com.shwfed.table.column.tree-combobox-multi/config.vue.d.ts +4 -4
- package/dist/runtime/components/table/columns/2026-05-27/com.shwfed.table.column.tree-combobox-single/config.d.vue.ts +2 -2
- package/dist/runtime/components/table/columns/2026-05-27/com.shwfed.table.column.tree-combobox-single/config.vue.d.ts +2 -2
- package/dist/runtime/components/table/columns/2026-05-28/com.shwfed.table.column.combobox-multi/config.d.vue.ts +28 -28
- package/dist/runtime/components/table/columns/2026-05-28/com.shwfed.table.column.combobox-multi/config.vue.d.ts +28 -28
- package/dist/runtime/components/table/columns/2026-05-28/com.shwfed.table.column.combobox-single/config.d.vue.ts +28 -28
- package/dist/runtime/components/table/columns/2026-05-28/com.shwfed.table.column.combobox-single/config.vue.d.ts +28 -28
- package/dist/runtime/components/table/columns/2026-05-28/com.shwfed.table.column.tree-combobox-multi/config.d.vue.ts +4 -4
- package/dist/runtime/components/table/columns/2026-05-28/com.shwfed.table.column.tree-combobox-multi/config.vue.d.ts +4 -4
- package/dist/runtime/components/table/columns/2026-05-28/com.shwfed.table.column.tree-combobox-single/config.d.vue.ts +2 -2
- package/dist/runtime/components/table/columns/2026-05-28/com.shwfed.table.column.tree-combobox-single/config.vue.d.ts +2 -2
- package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.combobox-multi/config.d.vue.ts +28 -28
- package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.combobox-multi/config.vue.d.ts +28 -28
- package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.combobox-single/config.d.vue.ts +28 -28
- package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.combobox-single/config.vue.d.ts +28 -28
- package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.tree-combobox-multi/config.d.vue.ts +4 -4
- package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.tree-combobox-multi/config.vue.d.ts +4 -4
- package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.tree-combobox-single/config.d.vue.ts +2 -2
- package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.tree-combobox-single/config.vue.d.ts +2 -2
- package/dist/runtime/components/table/columns/2026-06-17/com.shwfed.table.column.date-input/config.vue +33 -0
- package/dist/runtime/components/table/columns/2026-06-17/com.shwfed.table.column.date-input/runtime.vue +5 -0
- package/dist/runtime/components/table/columns/2026-06-17/com.shwfed.table.column.date-input/schema.d.ts +1 -0
- package/dist/runtime/components/table/columns/2026-06-17/com.shwfed.table.column.date-input/schema.js +6 -1
- package/dist/runtime/components/table/columns/2026-06-22/com.shwfed.table.column.date-range-input/config.vue +33 -0
- package/dist/runtime/components/table/columns/2026-06-22/com.shwfed.table.column.date-range-input/runtime.vue +5 -0
- package/dist/runtime/components/table/columns/2026-06-22/com.shwfed.table.column.date-range-input/schema.d.ts +1 -0
- package/dist/runtime/components/table/columns/2026-06-22/com.shwfed.table.column.date-range-input/schema.js +6 -1
- package/dist/runtime/components/table/utils/ai-tools.js +50 -1
- package/dist/runtime/components/table/utils/shared.d.ts +1 -0
- package/dist/runtime/components/table/utils/shared.js +10 -0
- package/dist/runtime/components/ui/alert-dialog/AlertDialogCancel.vue +1 -1
- package/dist/runtime/components/ui/chat/ChatPrompt.d.vue.ts +11 -1
- package/dist/runtime/components/ui/chat/ChatPrompt.vue +10 -0
- package/dist/runtime/components/ui/chat/ChatPrompt.vue.d.ts +11 -1
- package/dist/runtime/components/ui/expression-editor/CodeMirrorInput.d.vue.ts +1 -0
- package/dist/runtime/components/ui/expression-editor/CodeMirrorInput.vue +8 -0
- package/dist/runtime/components/ui/expression-editor/CodeMirrorInput.vue.d.ts +1 -0
- package/dist/runtime/components/ui/expression-editor/ExpressionEditor.d.vue.ts +3 -2
- package/dist/runtime/components/ui/expression-editor/ExpressionEditor.vue +51 -9
- package/dist/runtime/components/ui/expression-editor/ExpressionEditor.vue.d.ts +3 -2
- package/dist/runtime/components/ui/expression-editor/option-chip-extension.d.ts +4 -0
- package/dist/runtime/components/ui/expression-editor/option-chip-extension.js +119 -0
- package/dist/runtime/components/ui/expression-editor/option-refs.d.ts +6 -0
- package/dist/runtime/components/ui/expression-editor/option-refs.js +24 -0
- package/dist/runtime/components/ui/expression-editor/picker-entries.d.ts +2 -1
- package/dist/runtime/components/ui/expression-editor/picker-entries.js +12 -2
- package/dist/runtime/share/disabled-date.d.ts +34 -0
- package/dist/runtime/share/disabled-date.js +13 -0
- package/dist/runtime/utils/ai/index.js +24 -1
- package/dist/runtime/utils/cel-context.d.ts +1 -0
- package/dist/runtime/utils/cel-context.js +1 -0
- package/dist/runtime/utils/disabled-date.d.ts +26 -0
- package/dist/runtime/utils/disabled-date.js +21 -0
- package/dist/runtime/utils/selections-registry.d.ts +40 -6
- package/dist/runtime/utils/selections-registry.js +19 -4
- package/dist/runtime/vendor/cel-js/CLAUDE.md +2 -0
- package/dist/runtime/vendor/cel-js/PROMPT.md +2 -0
- package/dist/runtime/vendor/cel-js/lib/functions.js +33 -0
- package/package.json +1 -1
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { Facet, RangeSetBuilder } from "@codemirror/state";
|
|
2
|
+
import {
|
|
3
|
+
Decoration,
|
|
4
|
+
EditorView,
|
|
5
|
+
ViewPlugin,
|
|
6
|
+
WidgetType
|
|
7
|
+
} from "@codemirror/view";
|
|
8
|
+
import { scanOptionRefs } from "./option-refs.js";
|
|
9
|
+
export const optionLookupFacet = Facet.define({
|
|
10
|
+
combine: (values) => values.length > 0 ? values[values.length - 1] : /* @__PURE__ */ new Map()
|
|
11
|
+
});
|
|
12
|
+
class OptionChipWidget extends WidgetType {
|
|
13
|
+
constructor(id, name) {
|
|
14
|
+
super();
|
|
15
|
+
this.id = id;
|
|
16
|
+
this.name = name;
|
|
17
|
+
}
|
|
18
|
+
eq(other) {
|
|
19
|
+
return other.id === this.id && other.name === this.name;
|
|
20
|
+
}
|
|
21
|
+
toDOM() {
|
|
22
|
+
const chip = document.createElement("span");
|
|
23
|
+
chip.className = "cm-option-chip";
|
|
24
|
+
chip.setAttribute("data-option-id", this.id);
|
|
25
|
+
const tag = document.createElement("span");
|
|
26
|
+
tag.className = "cm-option-chip-tag";
|
|
27
|
+
tag.textContent = "\u5168\u90E8\u9009\u9879";
|
|
28
|
+
chip.appendChild(tag);
|
|
29
|
+
const text = document.createElement("span");
|
|
30
|
+
text.className = "cm-option-chip-label";
|
|
31
|
+
if (this.name !== null) {
|
|
32
|
+
text.textContent = this.name;
|
|
33
|
+
chip.title = `\u5168\u90E8\u9009\u9879 \xB7 ${this.name}`;
|
|
34
|
+
} else {
|
|
35
|
+
chip.classList.add("cm-option-chip-dangling");
|
|
36
|
+
const short = this.id.length > 8 ? `${this.id.slice(0, 8)}\u2026` : this.id;
|
|
37
|
+
text.textContent = short;
|
|
38
|
+
chip.title = `\u672A\u77E5\u5B57\u6BB5 ${this.id}`;
|
|
39
|
+
}
|
|
40
|
+
chip.appendChild(text);
|
|
41
|
+
return chip;
|
|
42
|
+
}
|
|
43
|
+
ignoreEvent() {
|
|
44
|
+
return false;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
function buildChips(view) {
|
|
48
|
+
const lookup = view.state.facet(optionLookupFacet);
|
|
49
|
+
const builder = new RangeSetBuilder();
|
|
50
|
+
for (const ref of scanOptionRefs(view.state.doc.toString())) {
|
|
51
|
+
const name = lookup.get(ref.id) ?? null;
|
|
52
|
+
builder.add(
|
|
53
|
+
ref.from,
|
|
54
|
+
ref.to,
|
|
55
|
+
Decoration.replace({ widget: new OptionChipWidget(ref.id, name) })
|
|
56
|
+
);
|
|
57
|
+
}
|
|
58
|
+
return builder.finish();
|
|
59
|
+
}
|
|
60
|
+
const chipPlugin = ViewPlugin.fromClass(
|
|
61
|
+
class {
|
|
62
|
+
decorations;
|
|
63
|
+
constructor(view) {
|
|
64
|
+
this.decorations = buildChips(view);
|
|
65
|
+
}
|
|
66
|
+
update(update) {
|
|
67
|
+
if (update.docChanged || update.viewportChanged || update.startState.facet(optionLookupFacet) !== update.state.facet(optionLookupFacet)) {
|
|
68
|
+
this.decorations = buildChips(update.view);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
decorations: (plugin) => plugin.decorations,
|
|
74
|
+
// Atomic so the caret steps over a chip and Backspace removes the whole
|
|
75
|
+
// `options["id"]` at once — matching the selection chip's delete-as-unit feel.
|
|
76
|
+
provide: (plugin) => EditorView.atomicRanges.of((view) => view.plugin(plugin)?.decorations ?? Decoration.none)
|
|
77
|
+
}
|
|
78
|
+
);
|
|
79
|
+
const chipTheme = EditorView.theme({
|
|
80
|
+
".cm-option-chip": {
|
|
81
|
+
display: "inline-flex",
|
|
82
|
+
alignItems: "center",
|
|
83
|
+
gap: "0.25rem",
|
|
84
|
+
margin: "0 1px",
|
|
85
|
+
padding: "0.125rem 0.25rem",
|
|
86
|
+
borderRadius: "0.25rem",
|
|
87
|
+
background: "#fffbeb",
|
|
88
|
+
border: "1px solid #fde68a",
|
|
89
|
+
color: "#b45309",
|
|
90
|
+
fontFamily: "ui-sans-serif, system-ui, sans-serif",
|
|
91
|
+
verticalAlign: "baseline",
|
|
92
|
+
cursor: "default",
|
|
93
|
+
whiteSpace: "nowrap"
|
|
94
|
+
},
|
|
95
|
+
".cm-option-chip-dangling": {
|
|
96
|
+
background: "#fef2f2",
|
|
97
|
+
borderColor: "#fecaca",
|
|
98
|
+
color: "#b91c1c"
|
|
99
|
+
},
|
|
100
|
+
".cm-option-chip-tag": {
|
|
101
|
+
borderRadius: "0.125rem",
|
|
102
|
+
background: "#fef3c7",
|
|
103
|
+
padding: "0.05rem 0.2rem",
|
|
104
|
+
fontSize: "9px",
|
|
105
|
+
lineHeight: "1",
|
|
106
|
+
color: "#d97706"
|
|
107
|
+
},
|
|
108
|
+
".cm-option-chip-dangling .cm-option-chip-tag": {
|
|
109
|
+
background: "#fee2e2",
|
|
110
|
+
color: "#b91c1c"
|
|
111
|
+
},
|
|
112
|
+
".cm-option-chip-label": {
|
|
113
|
+
fontSize: "0.75rem",
|
|
114
|
+
lineHeight: "1.1"
|
|
115
|
+
}
|
|
116
|
+
});
|
|
117
|
+
export function optionChips() {
|
|
118
|
+
return [chipPlugin, chipTheme];
|
|
119
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { OPTIONS_VAR } from "../../../utils/cel-context.js";
|
|
2
|
+
const OPTION_REF_RE = new RegExp(
|
|
3
|
+
`(?<![\\w$.])${OPTIONS_VAR}\\[\\??("(?:[^"\\\\]|\\\\.)*")\\]`,
|
|
4
|
+
"g"
|
|
5
|
+
);
|
|
6
|
+
export function scanOptionRefs(text) {
|
|
7
|
+
const out = [];
|
|
8
|
+
OPTION_REF_RE.lastIndex = 0;
|
|
9
|
+
let match;
|
|
10
|
+
while ((match = OPTION_REF_RE.exec(text)) !== null) {
|
|
11
|
+
let id;
|
|
12
|
+
try {
|
|
13
|
+
id = JSON.parse(match[1]);
|
|
14
|
+
} catch {
|
|
15
|
+
continue;
|
|
16
|
+
}
|
|
17
|
+
out.push({
|
|
18
|
+
from: match.index,
|
|
19
|
+
to: match.index + match[0].length,
|
|
20
|
+
id
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
return out;
|
|
24
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { type ScopeAncestor, type SelectionFieldRef, type StepRef } from '../../../utils/cel-context.js';
|
|
2
2
|
export type PickEntry = {
|
|
3
3
|
id: string;
|
|
4
|
-
group: 'var' | 'scope' | 'selection' | 'step';
|
|
4
|
+
group: 'var' | 'scope' | 'selection' | 'option' | 'step';
|
|
5
5
|
insert: string;
|
|
6
6
|
display: string;
|
|
7
7
|
label: string;
|
|
@@ -15,6 +15,7 @@ export type PickVarMeta = {
|
|
|
15
15
|
};
|
|
16
16
|
export declare function buildVarEntries(celContext: Record<string, PickVarMeta>, extraVars?: Record<string, PickVarMeta>): PickEntry[];
|
|
17
17
|
export declare function buildSelectionEntries(roster: ReadonlyArray<SelectionFieldRef>): PickEntry[];
|
|
18
|
+
export declare function buildOptionEntries(roster: ReadonlyArray<SelectionFieldRef>): PickEntry[];
|
|
18
19
|
export declare function buildStepEntries(roster: ReadonlyArray<StepRef>): PickEntry[];
|
|
19
20
|
export declare function selectShadowedScopes(ancestry: ReadonlyArray<ScopeAncestor>): ScopeAncestor[];
|
|
20
21
|
export declare function buildScopeEntries(ancestry: ReadonlyArray<ScopeAncestor>): PickEntry[];
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { SCOPE_ADDRESS_VAR, SELECTIONS_VAR, STEPS_VAR } from "../../../utils/cel-context.js";
|
|
1
|
+
import { OPTIONS_VAR, SCOPE_ADDRESS_VAR, SELECTIONS_VAR, STEPS_VAR } from "../../../utils/cel-context.js";
|
|
2
2
|
import { scopeOrigin } from "./scope-refs.js";
|
|
3
|
-
const SUPPRESSED_VARS = /* @__PURE__ */ new Set([SCOPE_ADDRESS_VAR, SELECTIONS_VAR, STEPS_VAR]);
|
|
3
|
+
const SUPPRESSED_VARS = /* @__PURE__ */ new Set([SCOPE_ADDRESS_VAR, SELECTIONS_VAR, OPTIONS_VAR, STEPS_VAR]);
|
|
4
4
|
export function buildVarEntries(celContext, extraVars) {
|
|
5
5
|
const out = [];
|
|
6
6
|
const seen = /* @__PURE__ */ new Set();
|
|
@@ -25,6 +25,16 @@ export function buildSelectionEntries(roster) {
|
|
|
25
25
|
type: "dyn"
|
|
26
26
|
}));
|
|
27
27
|
}
|
|
28
|
+
export function buildOptionEntries(roster) {
|
|
29
|
+
return roster.map((field) => ({
|
|
30
|
+
id: `option:${field.id}`,
|
|
31
|
+
group: "option",
|
|
32
|
+
insert: `${OPTIONS_VAR}[?${JSON.stringify(field.id)}]`,
|
|
33
|
+
display: field.name,
|
|
34
|
+
label: "\u5168\u90E8\u9009\u9879",
|
|
35
|
+
type: "dyn"
|
|
36
|
+
}));
|
|
37
|
+
}
|
|
28
38
|
export function buildStepEntries(roster) {
|
|
29
39
|
return roster.filter((step) => step.valid).map((step) => ({
|
|
30
40
|
id: `step:${step.id}`,
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { Environment } from '../vendor/cel-js/lib/index.js';
|
|
2
|
+
import type { ResultType } from './expression.js';
|
|
3
|
+
/**
|
|
4
|
+
* Result-type matcher for a per-date "should this date be disabled" expression.
|
|
5
|
+
* The expression returns `true` to disable the candidate date; `false`/none/
|
|
6
|
+
* absent leave it enabled (matching reka-ui's native `isDateDisabled`). Accepts
|
|
7
|
+
* a bare `bool` (`input >= now`) as well as `optional<bool>`
|
|
8
|
+
* (`cond ? optional.of(true) : optional.none()`) — same leniency as
|
|
9
|
+
* `HttpRequestResult` in `share/expression.ts`. At runtime `cel()` unwraps
|
|
10
|
+
* `optional.none()` to `undefined`, which the predicate treats as "no opinion,
|
|
11
|
+
* keep the date enabled". `dyn`/`optional<dyn>` ride along for gradual typing.
|
|
12
|
+
*/
|
|
13
|
+
export declare const DISABLE_DATE_RESULT: ResultType;
|
|
14
|
+
/**
|
|
15
|
+
* Register the `input` (Date) CEL variable — the candidate date the calendar is
|
|
16
|
+
* rendering — only when an enclosing `configure` hasn't already declared it. The
|
|
17
|
+
* CEL registry throws `'input' is already registered` on a duplicate, so the
|
|
18
|
+
* guard mirrors `registerRowVariablesIfAbsent` / `registerLoopVariablesIfAbsent`.
|
|
19
|
+
*/
|
|
20
|
+
export declare function registerInputDateIfAbsent(env: Environment): void;
|
|
21
|
+
/**
|
|
22
|
+
* The `input` variable advertised to `ExpressionEditor` via its `extra-vars`
|
|
23
|
+
* prop, so completion offers it at design time. Pair with
|
|
24
|
+
* `DISABLE_DATE_EDITOR_RESULT` for the editor's `result-type` — the editor prop
|
|
25
|
+
* can't take a function matcher, so the array form mirrors `DISABLE_DATE_RESULT`.
|
|
26
|
+
*/
|
|
27
|
+
export declare const INPUT_DATE_VARS: {
|
|
28
|
+
readonly input: {
|
|
29
|
+
readonly type: "Date";
|
|
30
|
+
readonly label: "候选日期";
|
|
31
|
+
readonly description: "日历中待判定是否可选的日期";
|
|
32
|
+
};
|
|
33
|
+
};
|
|
34
|
+
export declare const DISABLE_DATE_EDITOR_RESULT: readonly ["bool", "optional<bool>"];
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export const DISABLE_DATE_RESULT = (t) => t === "bool" || t === "optional<bool>" || t === "optional<dyn>" || t === "dyn";
|
|
2
|
+
const INPUT_VAR_LABEL = "\u5019\u9009\u65E5\u671F";
|
|
3
|
+
const INPUT_VAR_DESCRIPTION = "\u65E5\u5386\u4E2D\u5F85\u5224\u5B9A\u662F\u5426\u53EF\u9009\u7684\u65E5\u671F";
|
|
4
|
+
export function registerInputDateIfAbsent(env) {
|
|
5
|
+
const declared = new Set(env.getDefinitions().variables.map((v) => v.name));
|
|
6
|
+
if (!declared.has("input")) {
|
|
7
|
+
env.registerVariable("input", "Date", { label: INPUT_VAR_LABEL, description: INPUT_VAR_DESCRIPTION });
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
export const INPUT_DATE_VARS = {
|
|
11
|
+
input: { type: "Date", label: INPUT_VAR_LABEL, description: INPUT_VAR_DESCRIPTION }
|
|
12
|
+
};
|
|
13
|
+
export const DISABLE_DATE_EDITOR_RESULT = ["bool", "optional<bool>"];
|
|
@@ -5,7 +5,7 @@ import { coerceFromString } from "../../share/coerce-from-string.js";
|
|
|
5
5
|
const ENDPOINT = "http://192.168.168.10/anthropic/v1/messages";
|
|
6
6
|
const MODEL = "MiniMax-M2.7";
|
|
7
7
|
const ANTHROPIC_VERSION = "2023-06-01";
|
|
8
|
-
const DEFAULT_MAX_TOKENS =
|
|
8
|
+
const DEFAULT_MAX_TOKENS = 32768;
|
|
9
9
|
export class StructuredOutputDecodeError extends Error {
|
|
10
10
|
rawOutput;
|
|
11
11
|
constructor(rawOutput, cause) {
|
|
@@ -273,6 +273,8 @@ async function streamChat(input) {
|
|
|
273
273
|
};
|
|
274
274
|
const assistant = { id: createMessageId(), role: "assistant", parts: [] };
|
|
275
275
|
const publish = () => input.onMessageUpdate?.(assistant);
|
|
276
|
+
const MAX_TRUNCATION_STREAK = 3;
|
|
277
|
+
let truncationStreak = 0;
|
|
276
278
|
for (; ; ) {
|
|
277
279
|
const partByIndex = /* @__PURE__ */ new Map();
|
|
278
280
|
const response = await callStream(messages, input.system, opts, input.signal, () => {
|
|
@@ -313,8 +315,29 @@ async function streamChat(input) {
|
|
|
313
315
|
(b) => b.type === "tool_use"
|
|
314
316
|
);
|
|
315
317
|
if (toolUses.length === 0) {
|
|
318
|
+
if (response.stop_reason === "max_tokens") {
|
|
319
|
+
if (truncationStreak >= MAX_TRUNCATION_STREAK) {
|
|
320
|
+
throw new Error("\u6A21\u578B\u8FDE\u7EED\u591A\u8F6E\u5728\u4EA7\u51FA\u524D\u7528\u5C3D token \u9884\u7B97\uFF08max_tokens\uFF09\uFF0C\u5DF2\u505C\u6B62\u3002\u8BF7\u7F29\u5C0F\u672C\u6B21\u914D\u7F6E\u8303\u56F4\u6216\u62C6\u5206\u6307\u4EE4\u540E\u91CD\u8BD5\u3002");
|
|
321
|
+
}
|
|
322
|
+
truncationStreak++;
|
|
323
|
+
const echoable = response.content.filter(
|
|
324
|
+
(b) => !(b.type === "text" && b.text.length === 0)
|
|
325
|
+
);
|
|
326
|
+
const assistantEcho = echoable.length > 0 ? echoable : [{ type: "text", text: "\u2026" }];
|
|
327
|
+
messages.push({ role: "assistant", content: assistantEcho });
|
|
328
|
+
messages.push({
|
|
329
|
+
role: "user",
|
|
330
|
+
content: "\u4E0A\u4E00\u8F6E\u5728 max_tokens \u5904\u88AB\u622A\u65AD\u3002\u8BF7\u7528\u66F4\u5C0F\u7684\u6B65\u5B50\u7EE7\u7EED\uFF1A\u672C\u8F6E\u53EA\u505A\u4E00\u6B65\uFF08\u4E00\u4E2A\u5DE5\u5177\u8C03\u7528\uFF0C\u6216\u4E00\u6BB5\u7B80\u77ED\u56DE\u590D\uFF09\u3002"
|
|
331
|
+
});
|
|
332
|
+
if (assistant.parts.length > 0) {
|
|
333
|
+
assistant.parts.push({ type: "step-start" });
|
|
334
|
+
publish();
|
|
335
|
+
}
|
|
336
|
+
continue;
|
|
337
|
+
}
|
|
316
338
|
return assistant;
|
|
317
339
|
}
|
|
340
|
+
truncationStreak = 0;
|
|
318
341
|
await runToolResults(
|
|
319
342
|
messages,
|
|
320
343
|
response.content,
|
|
@@ -8,6 +8,7 @@ export type CELVar = {
|
|
|
8
8
|
export type CELContext = Record<string, CELVar>;
|
|
9
9
|
export declare const SCOPE_ADDRESS_VAR = "__scopes__";
|
|
10
10
|
export declare const SELECTIONS_VAR = "selections";
|
|
11
|
+
export declare const OPTIONS_VAR = "options";
|
|
11
12
|
export declare const STEPS_VAR = "steps";
|
|
12
13
|
export type ScopeAccessor = Record<string, () => unknown>;
|
|
13
14
|
export declare function provideCELContext(context: CELContext): void;
|
|
@@ -2,6 +2,7 @@ import { computed, inject, provide, shallowRef } from "vue";
|
|
|
2
2
|
import { injectLocal, provideLocal } from "@vueuse/core";
|
|
3
3
|
export const SCOPE_ADDRESS_VAR = "__scopes__";
|
|
4
4
|
export const SELECTIONS_VAR = "selections";
|
|
5
|
+
export const OPTIONS_VAR = "options";
|
|
5
6
|
export const STEPS_VAR = "steps";
|
|
6
7
|
const CEL_CONTEXT_KEY = Symbol("cel-context");
|
|
7
8
|
export function provideCELContext(context) {
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { DateValue } from 'reka-ui';
|
|
2
|
+
/**
|
|
3
|
+
* Convert an `@internationalized/date` `DateValue` (what the picker's
|
|
4
|
+
* `disabledDate` callback receives) to a native JS `Date`, so user expressions
|
|
5
|
+
* see a plain `input: Date`. Mirrors `pickerValueToNative` in
|
|
6
|
+
* `ui/date-picker/DatePicker.vue` (minus the `Time` branch — the per-date
|
|
7
|
+
* predicate never receives a `Time`). For a `CalendarDate` (date/month/year
|
|
8
|
+
* panels) the time fields are absent and default to `0`; for `month` panels the
|
|
9
|
+
* candidate is the first of the month (`day` is `1`).
|
|
10
|
+
*/
|
|
11
|
+
export declare function dateValueToNative(d: DateValue): Date;
|
|
12
|
+
/**
|
|
13
|
+
* Build the `(d: DateValue) => boolean` predicate the date pickers expect from a
|
|
14
|
+
* user-authored CEL expression. Centralizes three concerns shared by every date
|
|
15
|
+
* block: the `DateValue` → native `Date` conversion, the "expression returns
|
|
16
|
+
* `true` ⇒ date disabled" mapping (`false`/`undefined`/none ⇒ enabled — matching
|
|
17
|
+
* reka-ui's native `isDateDisabled`), and error containment (a throwing
|
|
18
|
+
* expression leaves the date enabled).
|
|
19
|
+
*
|
|
20
|
+
* Each runtime passes its own `evalWithInput` closure so its existing CEL scope
|
|
21
|
+
* is preserved verbatim — form fields evaluate against `{ form, input }`, table
|
|
22
|
+
* columns against `celScope(celContext, { input })`. Returns `undefined` when
|
|
23
|
+
* there's no expression, so the picker omits the prop and all dates stay
|
|
24
|
+
* selectable.
|
|
25
|
+
*/
|
|
26
|
+
export declare function makeDisabledDatePredicate(expr: string | undefined, evalWithInput: (input: Date) => boolean | undefined): ((d: DateValue) => boolean) | undefined;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export function dateValueToNative(d) {
|
|
2
|
+
return new Date(
|
|
3
|
+
d.year,
|
|
4
|
+
d.month - 1,
|
|
5
|
+
"day" in d ? d.day : 1,
|
|
6
|
+
"hour" in d ? d.hour : 0,
|
|
7
|
+
"hour" in d ? d.minute : 0,
|
|
8
|
+
"hour" in d ? d.second : 0
|
|
9
|
+
);
|
|
10
|
+
}
|
|
11
|
+
export function makeDisabledDatePredicate(expr, evalWithInput) {
|
|
12
|
+
if (!expr) return void 0;
|
|
13
|
+
return (d) => {
|
|
14
|
+
try {
|
|
15
|
+
return evalWithInput(dateValueToNative(d)) === true;
|
|
16
|
+
} catch (e) {
|
|
17
|
+
console.error("[shwfed] disabledDate expression failed", e);
|
|
18
|
+
return false;
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
}
|
|
@@ -38,17 +38,38 @@ export type SelectionsRegistry = {
|
|
|
38
38
|
clear: (uuid: string) => void;
|
|
39
39
|
};
|
|
40
40
|
/**
|
|
41
|
-
*
|
|
42
|
-
*
|
|
43
|
-
*
|
|
41
|
+
* The `options` channel is the exact same registry shape — a `uuid → value` map
|
|
42
|
+
* with the identical shallowRef + map-replace + identity-dedup discipline — but
|
|
43
|
+
* carries a field's WHOLE loaded option list (`options["<uuid>"]` → `[opt, …]`)
|
|
44
|
+
* rather than its selected option. A field owns both channels: `selections`
|
|
45
|
+
* publishes the picked option(s), `options` publishes every option it loaded.
|
|
46
|
+
* Kept under a separate injection key so the two maps are independent providers
|
|
47
|
+
* on the one host (the form root provides both). `OptionsRegistry` is a plain
|
|
48
|
+
* alias of `SelectionsRegistry` — the recursion-safety invariant is identical,
|
|
49
|
+
* so they must share the one implementation, never a drifting copy.
|
|
50
|
+
*/
|
|
51
|
+
export type OptionsRegistry = SelectionsRegistry;
|
|
52
|
+
/**
|
|
53
|
+
* Create the selections registry and provide it to descendants. The returned
|
|
54
|
+
* `entries` ref is what the host overlays as the `selections` CEL thunk.
|
|
44
55
|
*/
|
|
45
56
|
export declare function provideSelectionsRegistry(): SelectionsRegistry;
|
|
46
57
|
/**
|
|
47
|
-
*
|
|
48
|
-
*
|
|
49
|
-
|
|
58
|
+
* Create the options registry and provide it to descendants. The returned
|
|
59
|
+
* `entries` ref is what the host overlays as the `options` CEL thunk.
|
|
60
|
+
*/
|
|
61
|
+
export declare function provideOptionsRegistry(): OptionsRegistry;
|
|
62
|
+
/**
|
|
63
|
+
* Inject the nearest selections registry, or `undefined` when there's no
|
|
64
|
+
* providing host (an uncontrolled field, a unit test). Callers must tolerate the
|
|
65
|
+
* absent case — publishing is best-effort.
|
|
50
66
|
*/
|
|
51
67
|
export declare function useSelectionsRegistry(): SelectionsRegistry | undefined;
|
|
68
|
+
/**
|
|
69
|
+
* Inject the nearest options registry, or `undefined` when there's no providing
|
|
70
|
+
* host. Best-effort, same contract as `useSelectionsRegistry`.
|
|
71
|
+
*/
|
|
72
|
+
export declare function useOptionsRegistry(): OptionsRegistry | undefined;
|
|
52
73
|
/**
|
|
53
74
|
* Wire a selection field's publish lifecycle to the nearest registry. Call once
|
|
54
75
|
* in setup; it injects the host registry (tolerating absence), watches the
|
|
@@ -75,3 +96,16 @@ export declare function publishSelection<T>(key: string, resolved: () => T | und
|
|
|
75
96
|
identity: (value: T) => string;
|
|
76
97
|
raw: (value: T) => unknown;
|
|
77
98
|
}): void;
|
|
99
|
+
/**
|
|
100
|
+
* Wire a selection field's OPTIONS-list publish lifecycle to the nearest options
|
|
101
|
+
* registry. Same contract and de-dup discipline as `publishSelection` — the
|
|
102
|
+
* recursion hazard is identical (`celBindings` reads the `options` map on every
|
|
103
|
+
* `$cel` pass, and remote records are re-copied each pass), so `resolved` must
|
|
104
|
+
* return the whole loaded list, `identity` must project it to the STABLE joined
|
|
105
|
+
* option keys (never the payload), and `raw` projects it to the array stored for
|
|
106
|
+
* siblings to read. An empty list resolves to `undefined` → the entry clears.
|
|
107
|
+
*/
|
|
108
|
+
export declare function publishOptions<T>(key: string, resolved: () => T | undefined, project: {
|
|
109
|
+
identity: (value: T) => string;
|
|
110
|
+
raw: (value: T) => unknown;
|
|
111
|
+
}): void;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { inject, onUnmounted, provide, shallowRef, watch } from "vue";
|
|
2
2
|
const SELECTIONS_KEY = Symbol("shwfed-selections");
|
|
3
|
+
const OPTIONS_KEY = Symbol("shwfed-options");
|
|
3
4
|
function sameSelection(a, b) {
|
|
4
5
|
if (Object.is(a, b)) return true;
|
|
5
6
|
if (Array.isArray(a) && Array.isArray(b)) {
|
|
@@ -8,7 +9,7 @@ function sameSelection(a, b) {
|
|
|
8
9
|
}
|
|
9
10
|
return false;
|
|
10
11
|
}
|
|
11
|
-
|
|
12
|
+
function createRegistry(key) {
|
|
12
13
|
const entries = shallowRef({});
|
|
13
14
|
const registry = {
|
|
14
15
|
entries,
|
|
@@ -19,18 +20,29 @@ export function provideSelectionsRegistry() {
|
|
|
19
20
|
clear: (uuid) => {
|
|
20
21
|
if (!(uuid in entries.value)) return;
|
|
21
22
|
entries.value = Object.fromEntries(
|
|
22
|
-
Object.entries(entries.value).filter(([
|
|
23
|
+
Object.entries(entries.value).filter(([key2]) => key2 !== uuid)
|
|
23
24
|
);
|
|
24
25
|
}
|
|
25
26
|
};
|
|
26
|
-
provide(
|
|
27
|
+
provide(key, registry);
|
|
27
28
|
return registry;
|
|
28
29
|
}
|
|
30
|
+
export function provideSelectionsRegistry() {
|
|
31
|
+
return createRegistry(SELECTIONS_KEY);
|
|
32
|
+
}
|
|
33
|
+
export function provideOptionsRegistry() {
|
|
34
|
+
return createRegistry(OPTIONS_KEY);
|
|
35
|
+
}
|
|
29
36
|
export function useSelectionsRegistry() {
|
|
30
37
|
return inject(SELECTIONS_KEY, void 0);
|
|
31
38
|
}
|
|
39
|
+
export function useOptionsRegistry() {
|
|
40
|
+
return inject(OPTIONS_KEY, void 0);
|
|
41
|
+
}
|
|
32
42
|
export function publishSelection(key, resolved, project) {
|
|
33
|
-
|
|
43
|
+
publishTo(useSelectionsRegistry(), key, resolved, project);
|
|
44
|
+
}
|
|
45
|
+
function publishTo(registry, key, resolved, project) {
|
|
34
46
|
const NONE = "\0:none";
|
|
35
47
|
let last = "\0:init";
|
|
36
48
|
watch(
|
|
@@ -47,3 +59,6 @@ export function publishSelection(key, resolved, project) {
|
|
|
47
59
|
);
|
|
48
60
|
onUnmounted(() => registry?.clear(key));
|
|
49
61
|
}
|
|
62
|
+
export function publishOptions(key, resolved, project) {
|
|
63
|
+
publishTo(useOptionsRegistry(), key, resolved, project);
|
|
64
|
+
}
|
|
@@ -18,6 +18,8 @@ A `list.enumerate(): list<map<string, dyn>>` receiver method has been added (not
|
|
|
18
18
|
|
|
19
19
|
A `list.slice(number)` / `list.slice(number, number)` receiver pair has been added (not from upstream, in `functions.ts` beside `list.enumerate()`) — delegates straight to JS `Array.prototype.slice`, so negative indices count from the end (`list.slice(0, -1)` drops the last element) and out-of-range bounds clamp rather than throw. End is exclusive. Fills the gap left by CEL's `list[i]`, which has no negative indexing. Both overloads return `list<dyn>`.
|
|
20
20
|
|
|
21
|
+
A `string.replace(string, string): string` / `string.replace(string, string, number): string` receiver pair has been added (in `functions.ts` beside `string.trim()`), matching the CEL strings-extension `replace`. The two-arg form delegates to JS `String.prototype.replaceAll` (so all non-overlapping occurrences are replaced; an empty `from` interleaves `to`). The three-arg form takes a limit and mirrors Go's `strings.Replace` via the `replaceLimited` helper: `limit < 0` replaces all, `0` replaces none, otherwise the first `limit` occurrences (`"foo".replace("", "_", 2) == "_f_oo"`).
|
|
22
|
+
|
|
21
23
|
`evaluate` now returns `Effect<T, ParseError | EvaluationError | TypeError>` instead of a plain value. The entire evaluation pipeline is Effect-based — every AST node's `evaluate` function returns an Effect, and sub-expressions are composed via `Effect.gen` / `yield*`. Promise-based async handling has been removed. User-registered functions may return `Effect` values, which are automatically flatMapped into the evaluation pipeline. Import `Effect` from `effect` and use `Effect.runSync` or `Effect.runPromise` to execute the returned Effect.
|
|
22
24
|
|
|
23
25
|
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.
|
|
@@ -161,6 +161,8 @@ Mirrors JS `Array.prototype.slice`. Negative indices count from the end (CEL's `
|
|
|
161
161
|
"hello".indexOf("l") // 2
|
|
162
162
|
"hello".lastIndexOf("l") // 3
|
|
163
163
|
"hello".matches("[a-z]+") // true (regex)
|
|
164
|
+
"hello".replace("l", "L") // "heLLo" (all occurrences)
|
|
165
|
+
"hello".replace("l", "L", 1) // "heLlo" (first N; N<0 = all, 0 = none)
|
|
164
166
|
"a,b,c".split(",") // ["a", "b", "c"]
|
|
165
167
|
"a,b,c".split(",", 2) // ["a", "b,c"]
|
|
166
168
|
["a", "b"].join() // "ab"
|
|
@@ -139,6 +139,14 @@ export function registerFunctions(registry) {
|
|
|
139
139
|
functionOverload("string.lowerAscii(): string", (a) => a.toLowerCase());
|
|
140
140
|
functionOverload("string.upperAscii(): string", (a) => a.toUpperCase());
|
|
141
141
|
functionOverload("string.trim(): string", (a) => a.trim());
|
|
142
|
+
functionOverload(
|
|
143
|
+
"string.replace(string, string): string",
|
|
144
|
+
(string, from, to) => string.replaceAll(from, to)
|
|
145
|
+
);
|
|
146
|
+
functionOverload(
|
|
147
|
+
"string.replace(string, string, number): string",
|
|
148
|
+
(string, from, to, limit) => replaceLimited(string, from, to, toNum(limit))
|
|
149
|
+
);
|
|
142
150
|
functionOverload(
|
|
143
151
|
"string.indexOf(string): number",
|
|
144
152
|
(string, search) => Decimal.from(string.indexOf(search))
|
|
@@ -436,3 +444,28 @@ function stringSize(str) {
|
|
|
436
444
|
for (const _ of str) count++;
|
|
437
445
|
return count;
|
|
438
446
|
}
|
|
447
|
+
function replaceLimited(str, from, to, limit) {
|
|
448
|
+
if (limit < 0) return str.replaceAll(from, to);
|
|
449
|
+
if (limit === 0 || from === to) return str;
|
|
450
|
+
let result = "";
|
|
451
|
+
let start = 0;
|
|
452
|
+
let count = 0;
|
|
453
|
+
while (count < limit) {
|
|
454
|
+
let j;
|
|
455
|
+
if (from === "") {
|
|
456
|
+
if (count > 0) {
|
|
457
|
+
if (start >= str.length) break;
|
|
458
|
+
j = start + 1;
|
|
459
|
+
} else {
|
|
460
|
+
j = start;
|
|
461
|
+
}
|
|
462
|
+
} else {
|
|
463
|
+
j = str.indexOf(from, start);
|
|
464
|
+
if (j < 0) break;
|
|
465
|
+
}
|
|
466
|
+
result += str.slice(start, j) + to;
|
|
467
|
+
start = j + from.length;
|
|
468
|
+
count++;
|
|
469
|
+
}
|
|
470
|
+
return result + str.slice(start);
|
|
471
|
+
}
|