@wildwinter/expr-editor 0.15.3 → 0.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -0
- package/dist/index.cjs +29 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +25 -1
- package/dist/index.d.ts +25 -1
- package/dist/index.js +27 -4
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -35,6 +35,12 @@ Notable options beyond the basics:
|
|
|
35
35
|
multi-step flow (e.g. tag → operator → threshold) with no editor changes.
|
|
36
36
|
Templates without a wizard insert-then-refine: the editor auto-opens the
|
|
37
37
|
first unfilled slot of the inserted clause.
|
|
38
|
+
- `otherEngineScopes`: scopes another engine owns (a product family's shared
|
|
39
|
+
vocabulary, such as `patter` in a Storylets card). Their names never appear in
|
|
40
|
+
the host's catalogue, because the other engine checks them, so a reference into
|
|
41
|
+
one renders as an ordinary property pill with a tip saying whose it is, instead
|
|
42
|
+
of an unknown property. Accepted by the expression editor, the effects editor,
|
|
43
|
+
and the previews.
|
|
38
44
|
- **Qualities** (the `quality` property type) need nothing from the host beyond a
|
|
39
45
|
catalogue entry carrying `stages` — the ladder, in order. The editor then offers
|
|
40
46
|
the property in a comparison clause, gives it the **ordering** operators (a
|
package/dist/index.cjs
CHANGED
|
@@ -309,6 +309,20 @@ function searchCatalogue(entries, query, defaultScope) {
|
|
|
309
309
|
if (!q) return [...entries];
|
|
310
310
|
return entries.filter((e) => displayName(e, defaultScope).toLowerCase().includes(q) || (e.purpose ?? "").toLowerCase().includes(q));
|
|
311
311
|
}
|
|
312
|
+
function otherEngineTip(label) {
|
|
313
|
+
return `${label} belongs to another engine, which checks it`;
|
|
314
|
+
}
|
|
315
|
+
function propertyPillNote(entry, scope, label, otherEngineScopes) {
|
|
316
|
+
if (entry) {
|
|
317
|
+
const title = propertyTip(entry);
|
|
318
|
+
return title ? { title } : {};
|
|
319
|
+
}
|
|
320
|
+
if (otherEngineScopes?.includes(scope)) return { title: otherEngineTip(label) };
|
|
321
|
+
return { issue: `Unknown property ${label}` };
|
|
322
|
+
}
|
|
323
|
+
function scopeOfRef(ref) {
|
|
324
|
+
return /^@([^.\s]+)\./.exec(ref)?.[1];
|
|
325
|
+
}
|
|
312
326
|
function groupByScope(entries, scopeOrder = []) {
|
|
313
327
|
const byScope = /* @__PURE__ */ new Map();
|
|
314
328
|
for (const e of entries) {
|
|
@@ -482,11 +496,12 @@ function renderNode(node, path, ctx, parentOp, side) {
|
|
|
482
496
|
case "scopedvar": {
|
|
483
497
|
const entry = lookup(ctx.catalogue, node.scope, node.name);
|
|
484
498
|
const label = displayName({ scope: node.scope, name: node.name }, ctx.defaultScope);
|
|
499
|
+
const note = propertyPillNote(entry, node.scope, label, ctx.otherEngineScopes);
|
|
485
500
|
const varPill = pill(
|
|
486
501
|
"var",
|
|
487
502
|
label,
|
|
488
503
|
(b) => variableEditor(ctx, path, node, b),
|
|
489
|
-
{ issue: issue ??
|
|
504
|
+
{ issue: issue ?? note.issue, title: note.title }
|
|
490
505
|
);
|
|
491
506
|
attachPropertyMenu(ctx, node, varPill);
|
|
492
507
|
return varPill;
|
|
@@ -1167,6 +1182,7 @@ function mountExpressionEditor(host, opts) {
|
|
|
1167
1182
|
catalogue: opts.catalogue,
|
|
1168
1183
|
scopeOrder: opts.scopeOrder ?? [],
|
|
1169
1184
|
functions: opts.functions ?? [],
|
|
1185
|
+
...opts.otherEngineScopes ? { otherEngineScopes: opts.otherEngineScopes } : {},
|
|
1170
1186
|
byPath: v.byPath,
|
|
1171
1187
|
getAst: () => ast,
|
|
1172
1188
|
apply: (next) => emit(toSrc(next)),
|
|
@@ -1608,6 +1624,7 @@ function mountEffectsEditor(host, opts) {
|
|
|
1608
1624
|
scopeOrder: opts.scopeOrder,
|
|
1609
1625
|
functions: opts.functions,
|
|
1610
1626
|
mode: "flat",
|
|
1627
|
+
...opts.otherEngineScopes ? { otherEngineScopes: opts.otherEngineScopes } : {},
|
|
1611
1628
|
// Every editor here holds a VALUE (a set's value, an emit's argument), never a condition. Say
|
|
1612
1629
|
// so, or emptying one falls back to the condition empty state and an outcome row reads
|
|
1613
1630
|
// "always / + Add your first condition" - condition vocabulary, offering clauses where a value
|
|
@@ -1667,7 +1684,8 @@ function mountEffectsEditor(host, opts) {
|
|
|
1667
1684
|
});
|
|
1668
1685
|
}, "change the target property");
|
|
1669
1686
|
const targetEntry = entryForTarget(opts.catalogue, eff.target, defaultScope);
|
|
1670
|
-
const
|
|
1687
|
+
const targetScope = targetEntry ? void 0 : scopeOfRef(eff.target);
|
|
1688
|
+
const tip = targetScope !== void 0 && opts.otherEngineScopes?.includes(targetScope) ? otherEngineTip(eff.target) : propertyTip(targetEntry);
|
|
1671
1689
|
if (tip) targetBtn.title = tip;
|
|
1672
1690
|
if (targetEntry && opts.propertyActions) {
|
|
1673
1691
|
const actions = opts.propertyActions({ scope: targetEntry.scope, name: targetEntry.name });
|
|
@@ -1811,6 +1829,7 @@ function frozenCtx(src, o, selfAdvanceRef) {
|
|
|
1811
1829
|
catalogue: o.catalogue,
|
|
1812
1830
|
scopeOrder: o.scopeOrder ?? [],
|
|
1813
1831
|
functions: [],
|
|
1832
|
+
...o.otherEngineScopes ? { otherEngineScopes: o.otherEngineScopes } : {},
|
|
1814
1833
|
compact: true,
|
|
1815
1834
|
byPath: v.byPath,
|
|
1816
1835
|
getAst: () => v.ast,
|
|
@@ -1843,7 +1862,11 @@ function renderConditionPreview(src, o) {
|
|
|
1843
1862
|
function targetPill(ref, o) {
|
|
1844
1863
|
const pill2 = el("span", "exed-pill exed-pill-prop", [ref || "(property)"]);
|
|
1845
1864
|
const entry = o.catalogue.find((e) => refOf(e, o.dialect.defaultScope) === ref);
|
|
1846
|
-
if (!entry)
|
|
1865
|
+
if (!entry) {
|
|
1866
|
+
const scope = scopeOfRef(ref);
|
|
1867
|
+
if (scope !== void 0 && o.otherEngineScopes?.includes(scope)) pill2.title = otherEngineTip(ref);
|
|
1868
|
+
return pill2;
|
|
1869
|
+
}
|
|
1847
1870
|
const tip = propertyTip(entry);
|
|
1848
1871
|
if (tip) pill2.title = tip;
|
|
1849
1872
|
const actions = o.propertyActions?.({ scope: entry.scope, name: entry.name }) ?? [];
|
|
@@ -1924,8 +1947,10 @@ exports.normaliseRef = normaliseRef;
|
|
|
1924
1947
|
exports.notNode = notNode;
|
|
1925
1948
|
exports.numLit = numLit;
|
|
1926
1949
|
exports.opSwapGroup = opSwapGroup;
|
|
1950
|
+
exports.otherEngineTip = otherEngineTip;
|
|
1927
1951
|
exports.pathKey = pathKey;
|
|
1928
1952
|
exports.placeholderForOp = placeholderForOp;
|
|
1953
|
+
exports.propertyPillNote = propertyPillNote;
|
|
1929
1954
|
exports.propertyTip = propertyTip;
|
|
1930
1955
|
exports.redirectDeleteForPlaceholderSibling = redirectDeleteForPlaceholderSibling;
|
|
1931
1956
|
exports.refOf = refOf;
|
|
@@ -1934,6 +1959,7 @@ exports.removeAt = removeAt;
|
|
|
1934
1959
|
exports.renderConditionPreview = renderConditionPreview;
|
|
1935
1960
|
exports.renderEffectsPreview = renderEffectsPreview;
|
|
1936
1961
|
exports.rhsTypesFor = rhsTypesFor;
|
|
1962
|
+
exports.scopeOfRef = scopeOfRef;
|
|
1937
1963
|
exports.scopedVar = scopedVar;
|
|
1938
1964
|
exports.searchCatalogue = searchCatalogue;
|
|
1939
1965
|
exports.seedValueSrc = seedValueSrc;
|