@timeax/digital-service-engine 0.0.1 → 0.0.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/core/index.cjs +1097 -193
- package/dist/core/index.cjs.map +1 -1
- package/dist/core/index.d.cts +189 -51
- package/dist/core/index.d.ts +189 -51
- package/dist/core/index.js +1095 -193
- package/dist/core/index.js.map +1 -1
- package/dist/react/index.cjs +8313 -2542
- package/dist/react/index.cjs.map +1 -1
- package/dist/react/index.d.cts +401 -141
- package/dist/react/index.d.ts +401 -141
- package/dist/react/index.js +8471 -2709
- package/dist/react/index.js.map +1 -1
- package/dist/schema/index.d.cts +122 -54
- package/dist/schema/index.d.ts +122 -54
- package/dist/workspace/index.cjs +448 -239
- package/dist/workspace/index.cjs.map +1 -1
- package/dist/workspace/index.d.cts +54 -50
- package/dist/workspace/index.d.ts +54 -50
- package/dist/workspace/index.js +448 -239
- package/dist/workspace/index.js.map +1 -1
- package/package.json +15 -6
- package/schema/editor-snapshot.schema.json +121 -209
- package/schema/service-props.schema.json +121 -209
package/dist/workspace/index.js
CHANGED
|
@@ -3217,11 +3217,6 @@ function hasAnyServiceOption(f) {
|
|
|
3217
3217
|
var _a;
|
|
3218
3218
|
return ((_a = f.options) != null ? _a : []).some((o) => isFiniteNumber(o.service_id));
|
|
3219
3219
|
}
|
|
3220
|
-
function isBoundTo(f, tagId) {
|
|
3221
|
-
const b = f.bind_id;
|
|
3222
|
-
if (!b) return false;
|
|
3223
|
-
return Array.isArray(b) ? b.includes(tagId) : b === tagId;
|
|
3224
|
-
}
|
|
3225
3220
|
function getByPath(obj, path) {
|
|
3226
3221
|
if (!path) return void 0;
|
|
3227
3222
|
const parts = path.split(".");
|
|
@@ -3307,33 +3302,217 @@ function withAffected(details, ids) {
|
|
|
3307
3302
|
return { ...details != null ? details : {}, affectedIds: ids };
|
|
3308
3303
|
}
|
|
3309
3304
|
|
|
3305
|
+
// src/core/node-map.ts
|
|
3306
|
+
function buildNodeMap(props) {
|
|
3307
|
+
var _a, _b, _c;
|
|
3308
|
+
const map = /* @__PURE__ */ new Map();
|
|
3309
|
+
for (const t of (_a = props.filters) != null ? _a : []) {
|
|
3310
|
+
if (!map.has(t.id)) map.set(t.id, { kind: "tag", id: t.id, node: t });
|
|
3311
|
+
}
|
|
3312
|
+
for (const f of (_b = props.fields) != null ? _b : []) {
|
|
3313
|
+
if (!map.has(f.id)) map.set(f.id, { kind: "field", id: f.id, node: f });
|
|
3314
|
+
for (const o of (_c = f.options) != null ? _c : []) {
|
|
3315
|
+
if (!map.has(o.id))
|
|
3316
|
+
map.set(o.id, {
|
|
3317
|
+
kind: "option",
|
|
3318
|
+
id: o.id,
|
|
3319
|
+
node: o,
|
|
3320
|
+
fieldId: f.id
|
|
3321
|
+
});
|
|
3322
|
+
}
|
|
3323
|
+
}
|
|
3324
|
+
return map;
|
|
3325
|
+
}
|
|
3326
|
+
function resolveTrigger(trigger, nodeMap) {
|
|
3327
|
+
const idx = trigger.indexOf("::");
|
|
3328
|
+
if (idx !== -1) {
|
|
3329
|
+
const fieldId = trigger.slice(0, idx);
|
|
3330
|
+
const optionId = trigger.slice(idx + 2);
|
|
3331
|
+
return { kind: "composite", triggerKey: trigger, fieldId, optionId };
|
|
3332
|
+
}
|
|
3333
|
+
const direct = nodeMap.get(trigger);
|
|
3334
|
+
if (!direct) return void 0;
|
|
3335
|
+
if (direct.kind === "option") {
|
|
3336
|
+
return {
|
|
3337
|
+
kind: "option",
|
|
3338
|
+
triggerKey: trigger,
|
|
3339
|
+
id: direct.id,
|
|
3340
|
+
fieldId: direct.fieldId
|
|
3341
|
+
};
|
|
3342
|
+
}
|
|
3343
|
+
return { kind: direct.kind, triggerKey: trigger, id: direct.id };
|
|
3344
|
+
}
|
|
3345
|
+
|
|
3346
|
+
// src/core/visibility.ts
|
|
3347
|
+
function visibleFieldIdsUnder(props, tagId, opts = {}) {
|
|
3348
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
|
|
3349
|
+
const tags = (_a = props.filters) != null ? _a : [];
|
|
3350
|
+
const fields = (_b = props.fields) != null ? _b : [];
|
|
3351
|
+
const tagById = new Map(tags.map((t) => [t.id, t]));
|
|
3352
|
+
const tag = tagById.get(tagId);
|
|
3353
|
+
if (!tag) return [];
|
|
3354
|
+
const nodeMap = buildNodeMap(props);
|
|
3355
|
+
const lineageDepth = /* @__PURE__ */ new Map();
|
|
3356
|
+
{
|
|
3357
|
+
const guard = /* @__PURE__ */ new Set();
|
|
3358
|
+
let cur = tag;
|
|
3359
|
+
let d = 0;
|
|
3360
|
+
while (cur && !guard.has(cur.id)) {
|
|
3361
|
+
lineageDepth.set(cur.id, d++);
|
|
3362
|
+
guard.add(cur.id);
|
|
3363
|
+
const parentId = cur.bind_id;
|
|
3364
|
+
cur = parentId ? tagById.get(parentId) : void 0;
|
|
3365
|
+
}
|
|
3366
|
+
}
|
|
3367
|
+
const isTagInLineage = (id) => lineageDepth.has(id);
|
|
3368
|
+
const fieldById = new Map(fields.map((f) => [f.id, f]));
|
|
3369
|
+
const ownerDepthForField = (f) => {
|
|
3370
|
+
const b = f.bind_id;
|
|
3371
|
+
if (!b) return void 0;
|
|
3372
|
+
if (typeof b === "string") return lineageDepth.get(b);
|
|
3373
|
+
let best = void 0;
|
|
3374
|
+
for (const id of b) {
|
|
3375
|
+
const d = lineageDepth.get(id);
|
|
3376
|
+
if (d == null) continue;
|
|
3377
|
+
if (best == null || d < best) best = d;
|
|
3378
|
+
}
|
|
3379
|
+
return best;
|
|
3380
|
+
};
|
|
3381
|
+
const ownerDepthForTriggerKey = (triggerKey) => {
|
|
3382
|
+
const t = resolveTrigger(triggerKey, nodeMap);
|
|
3383
|
+
if (!t) return void 0;
|
|
3384
|
+
if (t.kind === "composite") {
|
|
3385
|
+
const f = fieldById.get(t.fieldId);
|
|
3386
|
+
if (!f) return void 0;
|
|
3387
|
+
return ownerDepthForField(f);
|
|
3388
|
+
}
|
|
3389
|
+
if (t.kind === "field") {
|
|
3390
|
+
const f = fieldById.get(t.id);
|
|
3391
|
+
if (!f || f.button !== true) return void 0;
|
|
3392
|
+
return ownerDepthForField(f);
|
|
3393
|
+
}
|
|
3394
|
+
if (t.kind === "option") {
|
|
3395
|
+
const f = t.fieldId ? fieldById.get(t.fieldId) : void 0;
|
|
3396
|
+
if (!f) return void 0;
|
|
3397
|
+
return ownerDepthForField(f);
|
|
3398
|
+
}
|
|
3399
|
+
return void 0;
|
|
3400
|
+
};
|
|
3401
|
+
const tagInclude = new Set((_c = tag.includes) != null ? _c : []);
|
|
3402
|
+
const tagExclude = new Set((_d = tag.excludes) != null ? _d : []);
|
|
3403
|
+
const selected = (_e = opts.selectedKeys) != null ? _e : /* @__PURE__ */ new Set();
|
|
3404
|
+
const incMap = (_f = props.includes_for_buttons) != null ? _f : {};
|
|
3405
|
+
const excMap = (_g = props.excludes_for_buttons) != null ? _g : {};
|
|
3406
|
+
const relevantTriggersInOrder = [];
|
|
3407
|
+
for (const key of selected) {
|
|
3408
|
+
const d = ownerDepthForTriggerKey(key);
|
|
3409
|
+
if (d == null) continue;
|
|
3410
|
+
relevantTriggersInOrder.push(key);
|
|
3411
|
+
}
|
|
3412
|
+
const visible = /* @__PURE__ */ new Set();
|
|
3413
|
+
const isBoundToLineage = (f) => {
|
|
3414
|
+
const b = f.bind_id;
|
|
3415
|
+
if (!b) return false;
|
|
3416
|
+
if (typeof b === "string") return isTagInLineage(b);
|
|
3417
|
+
for (const id of b) if (isTagInLineage(id)) return true;
|
|
3418
|
+
return false;
|
|
3419
|
+
};
|
|
3420
|
+
for (const f of fields) {
|
|
3421
|
+
if (isBoundToLineage(f)) visible.add(f.id);
|
|
3422
|
+
if (tagInclude.has(f.id)) visible.add(f.id);
|
|
3423
|
+
}
|
|
3424
|
+
for (const id of tagExclude) visible.delete(id);
|
|
3425
|
+
const decide = /* @__PURE__ */ new Map();
|
|
3426
|
+
const applyDecision = (fieldId, next) => {
|
|
3427
|
+
const prev = decide.get(fieldId);
|
|
3428
|
+
if (!prev) return void decide.set(fieldId, next);
|
|
3429
|
+
if (next.depth < prev.depth) return void decide.set(fieldId, next);
|
|
3430
|
+
if (next.depth > prev.depth) return;
|
|
3431
|
+
if (prev.kind === "include" && next.kind === "exclude") {
|
|
3432
|
+
decide.set(fieldId, next);
|
|
3433
|
+
}
|
|
3434
|
+
};
|
|
3435
|
+
const revealedOrder = [];
|
|
3436
|
+
const revealedSeen = /* @__PURE__ */ new Set();
|
|
3437
|
+
for (const triggerKey of relevantTriggersInOrder) {
|
|
3438
|
+
const depth = ownerDepthForTriggerKey(triggerKey);
|
|
3439
|
+
if (depth == null) continue;
|
|
3440
|
+
for (const id of (_h = incMap[triggerKey]) != null ? _h : []) {
|
|
3441
|
+
applyDecision(id, { depth, kind: "include" });
|
|
3442
|
+
if (!revealedSeen.has(id)) {
|
|
3443
|
+
revealedSeen.add(id);
|
|
3444
|
+
revealedOrder.push(id);
|
|
3445
|
+
}
|
|
3446
|
+
}
|
|
3447
|
+
for (const id of (_i = excMap[triggerKey]) != null ? _i : []) {
|
|
3448
|
+
applyDecision(id, { depth, kind: "exclude" });
|
|
3449
|
+
}
|
|
3450
|
+
}
|
|
3451
|
+
for (const [fid, d] of decide) {
|
|
3452
|
+
if (d.kind === "include") visible.add(fid);
|
|
3453
|
+
else visible.delete(fid);
|
|
3454
|
+
}
|
|
3455
|
+
const base = fields.filter((f) => visible.has(f.id)).map((f) => f.id);
|
|
3456
|
+
const order = (_j = props.order_for_tags) == null ? void 0 : _j[tagId];
|
|
3457
|
+
if (order && order.length) {
|
|
3458
|
+
const ordered = order.filter((fid) => visible.has(fid));
|
|
3459
|
+
const orderedSet = new Set(ordered);
|
|
3460
|
+
const rest2 = base.filter((fid) => !orderedSet.has(fid));
|
|
3461
|
+
return [...ordered, ...rest2];
|
|
3462
|
+
}
|
|
3463
|
+
const promoted = revealedOrder.filter((fid) => visible.has(fid));
|
|
3464
|
+
const promotedSet = new Set(promoted);
|
|
3465
|
+
const rest = base.filter((fid) => !promotedSet.has(fid));
|
|
3466
|
+
return [...promoted, ...rest];
|
|
3467
|
+
}
|
|
3468
|
+
function visibleFieldsUnder(props, tagId, opts = {}) {
|
|
3469
|
+
var _a;
|
|
3470
|
+
const ids = visibleFieldIdsUnder(props, tagId, opts);
|
|
3471
|
+
const fieldById = new Map(((_a = props.fields) != null ? _a : []).map((f) => [f.id, f]));
|
|
3472
|
+
return ids.map((id) => fieldById.get(id)).filter(Boolean);
|
|
3473
|
+
}
|
|
3474
|
+
|
|
3310
3475
|
// src/core/validate/steps/visibility.ts
|
|
3311
3476
|
function createFieldsVisibleUnder(v) {
|
|
3312
3477
|
return (tagId) => {
|
|
3313
|
-
|
|
3314
|
-
|
|
3315
|
-
|
|
3316
|
-
const excludesTag = new Set((_b = tag == null ? void 0 : tag.excludes) != null ? _b : []);
|
|
3317
|
-
const incForOpt = (_c = v.props.includes_for_buttons) != null ? _c : {};
|
|
3318
|
-
const excForOpt = (_d = v.props.excludes_for_buttons) != null ? _d : {};
|
|
3319
|
-
const includesOpt = /* @__PURE__ */ new Set();
|
|
3320
|
-
const excludesOpt = /* @__PURE__ */ new Set();
|
|
3321
|
-
for (const key of v.selectedKeys) {
|
|
3322
|
-
for (const id of (_e = incForOpt[key]) != null ? _e : []) includesOpt.add(id);
|
|
3323
|
-
for (const id of (_f = excForOpt[key]) != null ? _f : []) excludesOpt.add(id);
|
|
3324
|
-
}
|
|
3325
|
-
const merged = /* @__PURE__ */ new Map();
|
|
3326
|
-
for (const f of v.fields) {
|
|
3327
|
-
if (isBoundTo(f, tagId)) merged.set(f.id, f);
|
|
3328
|
-
if (includesTag.has(f.id)) merged.set(f.id, f);
|
|
3329
|
-
if (includesOpt.has(f.id)) merged.set(f.id, f);
|
|
3330
|
-
}
|
|
3331
|
-
for (const id of excludesTag) merged.delete(id);
|
|
3332
|
-
for (const id of excludesOpt) merged.delete(id);
|
|
3333
|
-
return Array.from(merged.values());
|
|
3478
|
+
return visibleFieldsUnder(v.props, tagId, {
|
|
3479
|
+
selectedKeys: v.selectedKeys
|
|
3480
|
+
});
|
|
3334
3481
|
};
|
|
3335
3482
|
}
|
|
3336
|
-
function
|
|
3483
|
+
function stableKeyOfSelection(keys) {
|
|
3484
|
+
return Array.from(keys).sort().join("|");
|
|
3485
|
+
}
|
|
3486
|
+
function resolveRootTags(tags) {
|
|
3487
|
+
const roots = tags.filter((t) => !t.bind_id);
|
|
3488
|
+
return roots.length ? roots : tags.slice(0, 1);
|
|
3489
|
+
}
|
|
3490
|
+
function isEffectfulTrigger(v, trigger) {
|
|
3491
|
+
var _a, _b, _c, _d, _e, _f;
|
|
3492
|
+
const inc = (_a = v.props.includes_for_buttons) != null ? _a : {};
|
|
3493
|
+
const exc = (_b = v.props.excludes_for_buttons) != null ? _b : {};
|
|
3494
|
+
return ((_d = (_c = inc[trigger]) == null ? void 0 : _c.length) != null ? _d : 0) > 0 || ((_f = (_e = exc[trigger]) == null ? void 0 : _e.length) != null ? _f : 0) > 0;
|
|
3495
|
+
}
|
|
3496
|
+
function collectSelectableTriggersInContext(v, tagId, selectedKeys, onlyEffectful) {
|
|
3497
|
+
var _a;
|
|
3498
|
+
const visible = visibleFieldsUnder(v.props, tagId, {
|
|
3499
|
+
selectedKeys
|
|
3500
|
+
});
|
|
3501
|
+
const triggers = [];
|
|
3502
|
+
for (const f of visible) {
|
|
3503
|
+
if (f.button === true) {
|
|
3504
|
+
const t = f.id;
|
|
3505
|
+
if (!onlyEffectful || isEffectfulTrigger(v, t)) triggers.push(t);
|
|
3506
|
+
}
|
|
3507
|
+
for (const o of (_a = f.options) != null ? _a : []) {
|
|
3508
|
+
const t = `${f.id}::${o.id}`;
|
|
3509
|
+
if (!onlyEffectful || isEffectfulTrigger(v, t)) triggers.push(t);
|
|
3510
|
+
}
|
|
3511
|
+
}
|
|
3512
|
+
triggers.sort();
|
|
3513
|
+
return triggers;
|
|
3514
|
+
}
|
|
3515
|
+
function runVisibilityRulesOnce(v) {
|
|
3337
3516
|
var _a, _b, _c, _d, _e;
|
|
3338
3517
|
for (const t of v.tags) {
|
|
3339
3518
|
const visible = v.fieldsVisibleUnder(t.id);
|
|
@@ -3408,12 +3587,85 @@ function validateVisibility(v) {
|
|
|
3408
3587
|
}
|
|
3409
3588
|
}
|
|
3410
3589
|
}
|
|
3590
|
+
function dedupeErrorsInPlace(v, startIndex) {
|
|
3591
|
+
const seen = /* @__PURE__ */ new Set();
|
|
3592
|
+
const keyOfErr = (e) => {
|
|
3593
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
|
|
3594
|
+
const tagId = (_e = (_d = (_a = e == null ? void 0 : e.details) == null ? void 0 : _a.tagId) != null ? _d : (_c = (_b = e == null ? void 0 : e.details) == null ? void 0 : _b.affected) == null ? void 0 : _c.tagId) != null ? _e : "";
|
|
3595
|
+
const other = (_g = (_f = e == null ? void 0 : e.details) == null ? void 0 : _f.other) != null ? _g : "";
|
|
3596
|
+
return `${(_h = e == null ? void 0 : e.code) != null ? _h : ""}::${(_i = e == null ? void 0 : e.nodeId) != null ? _i : ""}::${tagId}::${other}::${(_j = e == null ? void 0 : e.message) != null ? _j : ""}`;
|
|
3597
|
+
};
|
|
3598
|
+
const kept = [];
|
|
3599
|
+
for (let i = startIndex; i < v.errors.length; i++) {
|
|
3600
|
+
const e = v.errors[i];
|
|
3601
|
+
const k = keyOfErr(e);
|
|
3602
|
+
if (seen.has(k)) continue;
|
|
3603
|
+
seen.add(k);
|
|
3604
|
+
kept.push(e);
|
|
3605
|
+
}
|
|
3606
|
+
v.errors.splice(startIndex, v.errors.length - startIndex, ...kept);
|
|
3607
|
+
}
|
|
3608
|
+
function validateVisibility(v, options = {}) {
|
|
3609
|
+
var _a, _b, _c;
|
|
3610
|
+
const simulate = options.simulate === true;
|
|
3611
|
+
if (!simulate) {
|
|
3612
|
+
runVisibilityRulesOnce(v);
|
|
3613
|
+
return;
|
|
3614
|
+
}
|
|
3615
|
+
const maxStates = Math.max(1, (_a = options.maxStates) != null ? _a : 500);
|
|
3616
|
+
const maxDepth = Math.max(0, (_b = options.maxDepth) != null ? _b : 6);
|
|
3617
|
+
const onlyEffectful = options.onlyEffectfulTriggers !== false;
|
|
3618
|
+
const roots = resolveRootTags(v.tags);
|
|
3619
|
+
const rootTags = options.simulateAllRoots ? roots : roots.slice(0, 1);
|
|
3620
|
+
const originalSelected = new Set((_c = v.selectedKeys) != null ? _c : []);
|
|
3621
|
+
const errorsStart = v.errors.length;
|
|
3622
|
+
const visited = /* @__PURE__ */ new Set();
|
|
3623
|
+
const stack = [];
|
|
3624
|
+
for (const rt of rootTags) {
|
|
3625
|
+
stack.push({
|
|
3626
|
+
rootTagId: rt.id,
|
|
3627
|
+
selected: new Set(originalSelected),
|
|
3628
|
+
depth: 0
|
|
3629
|
+
});
|
|
3630
|
+
}
|
|
3631
|
+
let validatedStates = 0;
|
|
3632
|
+
while (stack.length) {
|
|
3633
|
+
if (validatedStates >= maxStates) break;
|
|
3634
|
+
const state = stack.pop();
|
|
3635
|
+
const sig = stableKeyOfSelection(state.selected);
|
|
3636
|
+
if (visited.has(sig)) continue;
|
|
3637
|
+
visited.add(sig);
|
|
3638
|
+
v.selectedKeys = state.selected;
|
|
3639
|
+
validatedStates++;
|
|
3640
|
+
runVisibilityRulesOnce(v);
|
|
3641
|
+
if (state.depth >= maxDepth) continue;
|
|
3642
|
+
const triggers = collectSelectableTriggersInContext(
|
|
3643
|
+
v,
|
|
3644
|
+
state.rootTagId,
|
|
3645
|
+
state.selected,
|
|
3646
|
+
onlyEffectful
|
|
3647
|
+
);
|
|
3648
|
+
for (let i = triggers.length - 1; i >= 0; i--) {
|
|
3649
|
+
const trig = triggers[i];
|
|
3650
|
+
if (state.selected.has(trig)) continue;
|
|
3651
|
+
const next = new Set(state.selected);
|
|
3652
|
+
next.add(trig);
|
|
3653
|
+
stack.push({
|
|
3654
|
+
rootTagId: state.rootTagId,
|
|
3655
|
+
selected: next,
|
|
3656
|
+
depth: state.depth + 1
|
|
3657
|
+
});
|
|
3658
|
+
}
|
|
3659
|
+
}
|
|
3660
|
+
v.selectedKeys = originalSelected;
|
|
3661
|
+
dedupeErrorsInPlace(v, errorsStart);
|
|
3662
|
+
}
|
|
3411
3663
|
|
|
3412
3664
|
// src/core/validate/steps/structure.ts
|
|
3413
3665
|
function validateStructure(v) {
|
|
3414
3666
|
const tags = v.tags;
|
|
3415
3667
|
const fields = v.fields;
|
|
3416
|
-
if (!tags.some((t) => t.id === "root")) {
|
|
3668
|
+
if (!tags.some((t) => t.id === "t:root")) {
|
|
3417
3669
|
v.errors.push({
|
|
3418
3670
|
code: "root_missing",
|
|
3419
3671
|
severity: "error",
|
|
@@ -3603,58 +3855,91 @@ function validateIdentity(v) {
|
|
|
3603
3855
|
}
|
|
3604
3856
|
|
|
3605
3857
|
// src/core/validate/steps/option-maps.ts
|
|
3858
|
+
function parseFieldOptionKey(key) {
|
|
3859
|
+
const idx = key.indexOf("::");
|
|
3860
|
+
if (idx === -1) return null;
|
|
3861
|
+
const fieldId = key.slice(0, idx).trim();
|
|
3862
|
+
const optionId = key.slice(idx + 2).trim();
|
|
3863
|
+
if (!fieldId || !optionId) return null;
|
|
3864
|
+
return { fieldId, optionId };
|
|
3865
|
+
}
|
|
3866
|
+
function hasOption(v, fid, oid) {
|
|
3867
|
+
var _a;
|
|
3868
|
+
const f = v.fieldById.get(fid);
|
|
3869
|
+
if (!f) return false;
|
|
3870
|
+
return !!((_a = f.options) != null ? _a : []).find((o) => o.id === oid);
|
|
3871
|
+
}
|
|
3606
3872
|
function validateOptionMaps(v) {
|
|
3607
3873
|
var _a, _b;
|
|
3608
3874
|
const incMap = (_a = v.props.includes_for_buttons) != null ? _a : {};
|
|
3609
3875
|
const excMap = (_b = v.props.excludes_for_buttons) != null ? _b : {};
|
|
3610
|
-
const
|
|
3611
|
-
|
|
3612
|
-
const
|
|
3613
|
-
|
|
3614
|
-
|
|
3615
|
-
|
|
3616
|
-
|
|
3617
|
-
|
|
3618
|
-
|
|
3619
|
-
|
|
3620
|
-
|
|
3621
|
-
|
|
3876
|
+
const badKeyMessage = (key) => `Invalid trigger-map key "${key}". Expected a known node id (option or button-field), or "fieldId::optionId" pointing to an existing option.`;
|
|
3877
|
+
const validateTriggerKey = (key) => {
|
|
3878
|
+
const ref = v.nodeMap.get(key);
|
|
3879
|
+
if (ref) {
|
|
3880
|
+
if (ref.kind === "option") {
|
|
3881
|
+
return {
|
|
3882
|
+
ok: true,
|
|
3883
|
+
nodeId: ref.fieldId,
|
|
3884
|
+
affected: [ref.fieldId, ref.id]
|
|
3885
|
+
};
|
|
3886
|
+
}
|
|
3887
|
+
if (ref.kind === "field") {
|
|
3888
|
+
const isButton = ref.node.button === true;
|
|
3889
|
+
if (!isButton)
|
|
3890
|
+
return { ok: false, nodeId: ref.id, affected: [ref.id] };
|
|
3891
|
+
return { ok: true, nodeId: ref.id, affected: [ref.id] };
|
|
3892
|
+
}
|
|
3893
|
+
return { ok: false, nodeId: ref.id, affected: [ref.id] };
|
|
3894
|
+
}
|
|
3895
|
+
const p = parseFieldOptionKey(key);
|
|
3896
|
+
if (!p) return { ok: false };
|
|
3897
|
+
if (!hasOption(v, p.fieldId, p.optionId))
|
|
3898
|
+
return {
|
|
3899
|
+
ok: false,
|
|
3900
|
+
nodeId: p.fieldId,
|
|
3901
|
+
affected: [p.fieldId, p.optionId]
|
|
3902
|
+
};
|
|
3903
|
+
return {
|
|
3904
|
+
ok: true,
|
|
3905
|
+
nodeId: p.fieldId,
|
|
3906
|
+
affected: [p.fieldId, p.optionId]
|
|
3907
|
+
};
|
|
3622
3908
|
};
|
|
3623
|
-
const badKeyMessage = (key) => `Invalid option-map key "${key}". Expected "fieldId::optionId" pointing to an existing option.`;
|
|
3624
3909
|
for (const k of Object.keys(incMap)) {
|
|
3625
|
-
const
|
|
3626
|
-
if (!
|
|
3910
|
+
const r = validateTriggerKey(k);
|
|
3911
|
+
if (!r.ok) {
|
|
3627
3912
|
v.errors.push({
|
|
3628
3913
|
code: "bad_option_key",
|
|
3629
3914
|
severity: "error",
|
|
3630
3915
|
message: badKeyMessage(k),
|
|
3631
|
-
|
|
3916
|
+
nodeId: r.nodeId,
|
|
3917
|
+
details: withAffected({ key: k }, r.affected)
|
|
3632
3918
|
});
|
|
3633
3919
|
}
|
|
3634
3920
|
}
|
|
3635
3921
|
for (const k of Object.keys(excMap)) {
|
|
3636
|
-
const
|
|
3637
|
-
if (!
|
|
3922
|
+
const r = validateTriggerKey(k);
|
|
3923
|
+
if (!r.ok) {
|
|
3638
3924
|
v.errors.push({
|
|
3639
3925
|
code: "bad_option_key",
|
|
3640
3926
|
severity: "error",
|
|
3641
3927
|
message: badKeyMessage(k),
|
|
3642
|
-
|
|
3928
|
+
nodeId: r.nodeId,
|
|
3929
|
+
details: withAffected({ key: k }, r.affected)
|
|
3643
3930
|
});
|
|
3644
3931
|
}
|
|
3645
3932
|
}
|
|
3646
3933
|
for (const k of Object.keys(incMap)) {
|
|
3647
|
-
if (k in excMap)
|
|
3648
|
-
|
|
3649
|
-
|
|
3650
|
-
|
|
3651
|
-
|
|
3652
|
-
|
|
3653
|
-
|
|
3654
|
-
|
|
3655
|
-
|
|
3656
|
-
});
|
|
3657
|
-
}
|
|
3934
|
+
if (!(k in excMap)) continue;
|
|
3935
|
+
const r = validateTriggerKey(k);
|
|
3936
|
+
v.errors.push({
|
|
3937
|
+
code: "option_include_exclude_conflict",
|
|
3938
|
+
severity: "error",
|
|
3939
|
+
message: `Trigger-map key "${k}" appears in both includes_for_buttons and excludes_for_buttons.`,
|
|
3940
|
+
nodeId: r.nodeId,
|
|
3941
|
+
details: withAffected({ key: k }, r.affected)
|
|
3942
|
+
});
|
|
3658
3943
|
}
|
|
3659
3944
|
}
|
|
3660
3945
|
|
|
@@ -4559,8 +4844,23 @@ function applyPolicies(errors, props, serviceMap, policies, fieldsVisibleUnder,
|
|
|
4559
4844
|
}
|
|
4560
4845
|
|
|
4561
4846
|
// src/core/validate/index.ts
|
|
4847
|
+
function readVisibilitySimOpts(ctx) {
|
|
4848
|
+
const c = ctx;
|
|
4849
|
+
const simulate = c.simulateVisibility === true || c.visibilitySimulate === true || c.simulate === true;
|
|
4850
|
+
const maxStates = typeof c.maxVisibilityStates === "number" ? c.maxVisibilityStates : typeof c.visibilityMaxStates === "number" ? c.visibilityMaxStates : typeof c.maxStates === "number" ? c.maxStates : void 0;
|
|
4851
|
+
const maxDepth = typeof c.maxVisibilityDepth === "number" ? c.maxVisibilityDepth : typeof c.visibilityMaxDepth === "number" ? c.visibilityMaxDepth : typeof c.maxDepth === "number" ? c.maxDepth : void 0;
|
|
4852
|
+
const simulateAllRoots = c.simulateAllRoots === true || c.visibilitySimulateAllRoots === true;
|
|
4853
|
+
const onlyEffectfulTriggers = c.onlyEffectfulTriggers === false ? false : c.visibilityOnlyEffectfulTriggers !== false;
|
|
4854
|
+
return {
|
|
4855
|
+
simulate,
|
|
4856
|
+
maxStates,
|
|
4857
|
+
maxDepth,
|
|
4858
|
+
simulateAllRoots,
|
|
4859
|
+
onlyEffectfulTriggers
|
|
4860
|
+
};
|
|
4861
|
+
}
|
|
4562
4862
|
function validate(props, ctx = {}) {
|
|
4563
|
-
var _a, _b;
|
|
4863
|
+
var _a, _b, _c;
|
|
4564
4864
|
const errors = [];
|
|
4565
4865
|
const serviceMap = (_a = ctx.serviceMap) != null ? _a : {};
|
|
4566
4866
|
const selectedKeys = new Set(
|
|
@@ -4574,6 +4874,7 @@ function validate(props, ctx = {}) {
|
|
|
4574
4874
|
for (const f of fields) fieldById.set(f.id, f);
|
|
4575
4875
|
const v = {
|
|
4576
4876
|
props,
|
|
4877
|
+
nodeMap: (_c = ctx.nodeMap) != null ? _c : buildNodeMap(props),
|
|
4577
4878
|
options: ctx,
|
|
4578
4879
|
errors,
|
|
4579
4880
|
serviceMap,
|
|
@@ -4588,7 +4889,8 @@ function validate(props, ctx = {}) {
|
|
|
4588
4889
|
validateIdentity(v);
|
|
4589
4890
|
validateOptionMaps(v);
|
|
4590
4891
|
v.fieldsVisibleUnder = createFieldsVisibleUnder(v);
|
|
4591
|
-
|
|
4892
|
+
const visSim = readVisibilitySimOpts(ctx);
|
|
4893
|
+
validateVisibility(v, visSim);
|
|
4592
4894
|
applyPolicies(
|
|
4593
4895
|
v.errors,
|
|
4594
4896
|
v.props,
|
|
@@ -4624,11 +4926,21 @@ var BuilderImpl = class {
|
|
|
4624
4926
|
this.optionOwnerById = /* @__PURE__ */ new Map();
|
|
4625
4927
|
this.history = [];
|
|
4626
4928
|
this.future = [];
|
|
4929
|
+
this._nodemap = null;
|
|
4627
4930
|
var _a;
|
|
4628
4931
|
this.options = { ...opts };
|
|
4629
4932
|
this.historyLimit = (_a = opts.historyLimit) != null ? _a : 50;
|
|
4630
4933
|
}
|
|
4631
4934
|
/* ───── lifecycle ─────────────────────────────────────────────────────── */
|
|
4935
|
+
isTagId(id) {
|
|
4936
|
+
return this.tagById.has(id);
|
|
4937
|
+
}
|
|
4938
|
+
isFieldId(id) {
|
|
4939
|
+
return this.fieldById.has(id);
|
|
4940
|
+
}
|
|
4941
|
+
isOptionId(id) {
|
|
4942
|
+
return this.optionOwnerById.has(id);
|
|
4943
|
+
}
|
|
4632
4944
|
load(raw) {
|
|
4633
4945
|
const next = normalise(raw, {
|
|
4634
4946
|
defaultPricingRole: "base",
|
|
@@ -4848,129 +5160,16 @@ var BuilderImpl = class {
|
|
|
4848
5160
|
return validate(this.props, this.options);
|
|
4849
5161
|
}
|
|
4850
5162
|
visibleFields(tagId, selectedKeys) {
|
|
4851
|
-
var _a
|
|
4852
|
-
|
|
4853
|
-
|
|
4854
|
-
|
|
4855
|
-
|
|
4856
|
-
|
|
4857
|
-
|
|
4858
|
-
|
|
4859
|
-
|
|
4860
|
-
|
|
4861
|
-
let cur = tag;
|
|
4862
|
-
let d = 0;
|
|
4863
|
-
while (cur && !guard.has(cur.id)) {
|
|
4864
|
-
lineageDepth.set(cur.id, d++);
|
|
4865
|
-
guard.add(cur.id);
|
|
4866
|
-
const parentId = cur.bind_id;
|
|
4867
|
-
cur = parentId ? tagById.get(parentId) : void 0;
|
|
4868
|
-
}
|
|
4869
|
-
}
|
|
4870
|
-
const isTagInLineage = (id) => lineageDepth.has(id);
|
|
4871
|
-
const fieldById = new Map(fields.map((f) => [f.id, f]));
|
|
4872
|
-
const optionOwnerFieldId = /* @__PURE__ */ new Map();
|
|
4873
|
-
for (const f of fields) {
|
|
4874
|
-
for (const o of (_c = f.options) != null ? _c : []) optionOwnerFieldId.set(o.id, f.id);
|
|
4875
|
-
}
|
|
4876
|
-
const ownerDepthForField = (f) => {
|
|
4877
|
-
const b = f.bind_id;
|
|
4878
|
-
if (!b) return void 0;
|
|
4879
|
-
if (typeof b === "string") return lineageDepth.get(b);
|
|
4880
|
-
let best = void 0;
|
|
4881
|
-
for (const id of b) {
|
|
4882
|
-
const d = lineageDepth.get(id);
|
|
4883
|
-
if (d == null) continue;
|
|
4884
|
-
if (best == null || d < best) best = d;
|
|
4885
|
-
}
|
|
4886
|
-
return best;
|
|
4887
|
-
};
|
|
4888
|
-
const ownerDepthForTrigger = (triggerId) => {
|
|
4889
|
-
if (triggerId.startsWith("o:")) {
|
|
4890
|
-
const fid = optionOwnerFieldId.get(triggerId);
|
|
4891
|
-
if (!fid) return void 0;
|
|
4892
|
-
const f2 = fieldById.get(fid);
|
|
4893
|
-
if (!f2) return void 0;
|
|
4894
|
-
return ownerDepthForField(f2);
|
|
4895
|
-
}
|
|
4896
|
-
const f = fieldById.get(triggerId);
|
|
4897
|
-
if (!f || f.button !== true) return void 0;
|
|
4898
|
-
return ownerDepthForField(f);
|
|
4899
|
-
};
|
|
4900
|
-
const tagInclude = new Set((_d = tag.includes) != null ? _d : []);
|
|
4901
|
-
const tagExclude = new Set((_e = tag.excludes) != null ? _e : []);
|
|
4902
|
-
const selected = new Set(
|
|
4903
|
-
(_f = selectedKeys != null ? selectedKeys : this.options.selectedOptionKeys) != null ? _f : []
|
|
4904
|
-
);
|
|
4905
|
-
const incMap = (_g = props.includes_for_buttons) != null ? _g : {};
|
|
4906
|
-
const excMap = (_h = props.excludes_for_buttons) != null ? _h : {};
|
|
4907
|
-
const relevantTriggersInOrder = [];
|
|
4908
|
-
for (const key of selected) {
|
|
4909
|
-
const d = ownerDepthForTrigger(key);
|
|
4910
|
-
if (d == null) continue;
|
|
4911
|
-
relevantTriggersInOrder.push(key);
|
|
4912
|
-
}
|
|
4913
|
-
const visible = /* @__PURE__ */ new Set();
|
|
4914
|
-
const isBoundToLineage = (f) => {
|
|
4915
|
-
const b = f.bind_id;
|
|
4916
|
-
if (!b) return false;
|
|
4917
|
-
if (typeof b === "string") return isTagInLineage(b);
|
|
4918
|
-
for (const id of b) if (isTagInLineage(id)) return true;
|
|
4919
|
-
return false;
|
|
4920
|
-
};
|
|
4921
|
-
for (const f of fields) {
|
|
4922
|
-
if (isBoundToLineage(f)) visible.add(f.id);
|
|
4923
|
-
if (tagInclude.has(f.id)) visible.add(f.id);
|
|
4924
|
-
}
|
|
4925
|
-
for (const id of tagExclude) visible.delete(id);
|
|
4926
|
-
const decide = /* @__PURE__ */ new Map();
|
|
4927
|
-
const applyDecision = (fieldId, next) => {
|
|
4928
|
-
const prev = decide.get(fieldId);
|
|
4929
|
-
if (!prev) {
|
|
4930
|
-
decide.set(fieldId, next);
|
|
4931
|
-
return;
|
|
4932
|
-
}
|
|
4933
|
-
if (next.depth < prev.depth) {
|
|
4934
|
-
decide.set(fieldId, next);
|
|
4935
|
-
return;
|
|
4936
|
-
}
|
|
4937
|
-
if (next.depth > prev.depth) return;
|
|
4938
|
-
if (prev.kind === "include" && next.kind === "exclude") {
|
|
4939
|
-
decide.set(fieldId, next);
|
|
4940
|
-
}
|
|
4941
|
-
};
|
|
4942
|
-
const revealedOrder = [];
|
|
4943
|
-
const revealedSeen = /* @__PURE__ */ new Set();
|
|
4944
|
-
for (const triggerId of relevantTriggersInOrder) {
|
|
4945
|
-
const depth = ownerDepthForTrigger(triggerId);
|
|
4946
|
-
if (depth == null) continue;
|
|
4947
|
-
for (const id of (_i = incMap[triggerId]) != null ? _i : []) {
|
|
4948
|
-
applyDecision(id, { depth, kind: "include" });
|
|
4949
|
-
if (!revealedSeen.has(id)) {
|
|
4950
|
-
revealedSeen.add(id);
|
|
4951
|
-
revealedOrder.push(id);
|
|
4952
|
-
}
|
|
4953
|
-
}
|
|
4954
|
-
for (const id of (_j = excMap[triggerId]) != null ? _j : []) {
|
|
4955
|
-
applyDecision(id, { depth, kind: "exclude" });
|
|
4956
|
-
}
|
|
4957
|
-
}
|
|
4958
|
-
for (const [fid, d] of decide) {
|
|
4959
|
-
if (d.kind === "include") visible.add(fid);
|
|
4960
|
-
else visible.delete(fid);
|
|
4961
|
-
}
|
|
4962
|
-
const base = fields.filter((f) => visible.has(f.id)).map((f) => f.id);
|
|
4963
|
-
const order = (_k = props.order_for_tags) == null ? void 0 : _k[tagId];
|
|
4964
|
-
if (order && order.length) {
|
|
4965
|
-
const ordered = order.filter((fid) => visible.has(fid));
|
|
4966
|
-
const orderedSet = new Set(ordered);
|
|
4967
|
-
const rest2 = base.filter((fid) => !orderedSet.has(fid));
|
|
4968
|
-
return [...ordered, ...rest2];
|
|
4969
|
-
}
|
|
4970
|
-
const promoted = revealedOrder.filter((fid) => visible.has(fid));
|
|
4971
|
-
const promotedSet = new Set(promoted);
|
|
4972
|
-
const rest = base.filter((fid) => !promotedSet.has(fid));
|
|
4973
|
-
return [...promoted, ...rest];
|
|
5163
|
+
var _a;
|
|
5164
|
+
return visibleFieldIdsUnder(this.props, tagId, {
|
|
5165
|
+
selectedKeys: new Set(
|
|
5166
|
+
(_a = selectedKeys != null ? selectedKeys : this.options.selectedOptionKeys) != null ? _a : []
|
|
5167
|
+
)
|
|
5168
|
+
});
|
|
5169
|
+
}
|
|
5170
|
+
getNodeMap() {
|
|
5171
|
+
if (!this._nodemap) this._nodemap = buildNodeMap(this.getProps());
|
|
5172
|
+
return this._nodemap;
|
|
4974
5173
|
}
|
|
4975
5174
|
/* ───── history ─────────────────────────────────────────────────────── */
|
|
4976
5175
|
undo() {
|
|
@@ -4994,6 +5193,7 @@ var BuilderImpl = class {
|
|
|
4994
5193
|
this.tagById.clear();
|
|
4995
5194
|
this.fieldById.clear();
|
|
4996
5195
|
this.optionOwnerById.clear();
|
|
5196
|
+
this._nodemap = null;
|
|
4997
5197
|
for (const t of this.props.filters) this.tagById.set(t.id, t);
|
|
4998
5198
|
for (const f of this.props.fields) {
|
|
4999
5199
|
this.fieldById.set(f.id, f);
|
|
@@ -5221,6 +5421,7 @@ var toBindList = (b) => {
|
|
|
5221
5421
|
function createNodeIndex(builder) {
|
|
5222
5422
|
var _a, _b, _c, _d;
|
|
5223
5423
|
const props = builder.getProps();
|
|
5424
|
+
const nodeMap = builder.getNodeMap();
|
|
5224
5425
|
const tags = (_a = props.filters) != null ? _a : [];
|
|
5225
5426
|
const fields = (_b = props.fields) != null ? _b : [];
|
|
5226
5427
|
const tagById = new Map(tags.map((t) => [t.id, t]));
|
|
@@ -5424,7 +5625,9 @@ function createNodeIndex(builder) {
|
|
|
5424
5625
|
return parentById.get(id) === tid;
|
|
5425
5626
|
},
|
|
5426
5627
|
getDescendant(descendantId) {
|
|
5427
|
-
return this.getDescendants().find(
|
|
5628
|
+
return this.getDescendants().find(
|
|
5629
|
+
(item) => item.id == descendantId
|
|
5630
|
+
);
|
|
5428
5631
|
},
|
|
5429
5632
|
getDescendants() {
|
|
5430
5633
|
const results = [];
|
|
@@ -5433,7 +5636,9 @@ function createNodeIndex(builder) {
|
|
|
5433
5636
|
const node2 = getField(fieldId);
|
|
5434
5637
|
if (!node2) continue;
|
|
5435
5638
|
const explicit = includes.has(fieldId) || isFieldBoundDirectToTag(fieldId, id);
|
|
5436
|
-
results.push(
|
|
5639
|
+
results.push(
|
|
5640
|
+
explicit ? node2 : { ...node2, isInherited: true }
|
|
5641
|
+
);
|
|
5437
5642
|
}
|
|
5438
5643
|
return Object.freeze(results);
|
|
5439
5644
|
}
|
|
@@ -5482,7 +5687,9 @@ function createNodeIndex(builder) {
|
|
|
5482
5687
|
return false;
|
|
5483
5688
|
},
|
|
5484
5689
|
getDescendant(descendantId, context) {
|
|
5485
|
-
return this.getDescendants(context).find(
|
|
5690
|
+
return this.getDescendants(context).find(
|
|
5691
|
+
(item) => item.id == descendantId
|
|
5692
|
+
);
|
|
5486
5693
|
},
|
|
5487
5694
|
getDescendants(tagId) {
|
|
5488
5695
|
return resolveDescendants(id, includes, tagId, !isButton);
|
|
@@ -5524,7 +5731,9 @@ function createNodeIndex(builder) {
|
|
|
5524
5731
|
return owner.isBoundTo(tagId);
|
|
5525
5732
|
},
|
|
5526
5733
|
getDescendant(descendantId, context) {
|
|
5527
|
-
return this.getDescendants(context).find(
|
|
5734
|
+
return this.getDescendants(context).find(
|
|
5735
|
+
(item) => item.id == descendantId
|
|
5736
|
+
);
|
|
5528
5737
|
},
|
|
5529
5738
|
getDescendants(tagId) {
|
|
5530
5739
|
return resolveDescendants(id, includes, tagId);
|
|
@@ -5535,7 +5744,7 @@ function createNodeIndex(builder) {
|
|
|
5535
5744
|
return node;
|
|
5536
5745
|
};
|
|
5537
5746
|
const getNode = (input) => {
|
|
5538
|
-
var _a2, _b2, _c2, _d2, _e
|
|
5747
|
+
var _a2, _b2, _c2, _d2, _e;
|
|
5539
5748
|
if (typeof input !== "string") {
|
|
5540
5749
|
if ("bind_id" in input && !("type" in input))
|
|
5541
5750
|
return (_a2 = getTag(input.id)) != null ? _a2 : mkUnknown(input.id);
|
|
@@ -5545,11 +5754,7 @@ function createNodeIndex(builder) {
|
|
|
5545
5754
|
}
|
|
5546
5755
|
const cached = nodeCache.get(input);
|
|
5547
5756
|
if (cached) return cached;
|
|
5548
|
-
|
|
5549
|
-
if (id.startsWith("t:")) return (_d2 = getTag(id)) != null ? _d2 : mkUnknown(id);
|
|
5550
|
-
if (id.startsWith("f:")) return (_e = getField(id)) != null ? _e : mkUnknown(id);
|
|
5551
|
-
if (id.startsWith("o:")) return (_f = getOption(id)) != null ? _f : mkUnknown(id);
|
|
5552
|
-
return (_i = (_h = (_g = getTag(id)) != null ? _g : getField(id)) != null ? _h : getOption(id)) != null ? _i : mkUnknown(id);
|
|
5757
|
+
return (_e = (_d2 = nodeMap.get(input)) == null ? void 0 : _d2.node) != null ? _e : mkUnknown(input);
|
|
5553
5758
|
};
|
|
5554
5759
|
const mkUnknown = (id) => {
|
|
5555
5760
|
const u = {
|
|
@@ -5609,9 +5814,6 @@ function rateOk(svcMap, candidate, primary, policy) {
|
|
|
5609
5814
|
|
|
5610
5815
|
// src/react/canvas/editor.ts
|
|
5611
5816
|
var MAX_LIMIT = 100;
|
|
5612
|
-
var isTagId = (id) => id.startsWith("t:");
|
|
5613
|
-
var isFieldId = (id) => id.startsWith("f:");
|
|
5614
|
-
var isOptionId = (id) => id.startsWith("o:");
|
|
5615
5817
|
function ownerOfOption(props, optionId) {
|
|
5616
5818
|
var _a, _b;
|
|
5617
5819
|
for (const f of (_a = props.fields) != null ? _a : []) {
|
|
@@ -5653,6 +5855,15 @@ var Editor = class {
|
|
|
5653
5855
|
this.pushHistory(this.makeSnapshot("init"));
|
|
5654
5856
|
}
|
|
5655
5857
|
/* ───────────────────────── Public API ───────────────────────── */
|
|
5858
|
+
isTagId(id) {
|
|
5859
|
+
return this.builder.isTagId(id);
|
|
5860
|
+
}
|
|
5861
|
+
isFieldId(id) {
|
|
5862
|
+
return this.builder.isFieldId(id);
|
|
5863
|
+
}
|
|
5864
|
+
isOptionId(id) {
|
|
5865
|
+
return this.builder.isOptionId(id);
|
|
5866
|
+
}
|
|
5656
5867
|
getProps() {
|
|
5657
5868
|
return this.builder.getProps();
|
|
5658
5869
|
}
|
|
@@ -5748,7 +5959,7 @@ var Editor = class {
|
|
|
5748
5959
|
name: "reLabel",
|
|
5749
5960
|
do: () => this.patchProps((p) => {
|
|
5750
5961
|
var _a, _b, _c, _d, _e, _f, _g;
|
|
5751
|
-
if (isTagId(id)) {
|
|
5962
|
+
if (this.isTagId(id)) {
|
|
5752
5963
|
const t = ((_a = p.filters) != null ? _a : []).find((x) => x.id === id);
|
|
5753
5964
|
if (!t) return;
|
|
5754
5965
|
if (((_b = t.label) != null ? _b : "") === label) return;
|
|
@@ -5756,7 +5967,7 @@ var Editor = class {
|
|
|
5756
5967
|
this.api.refreshGraph();
|
|
5757
5968
|
return;
|
|
5758
5969
|
}
|
|
5759
|
-
if (isOptionId(id)) {
|
|
5970
|
+
if (this.isOptionId(id)) {
|
|
5760
5971
|
const own = ownerOfOption(p, id);
|
|
5761
5972
|
if (!own) return;
|
|
5762
5973
|
const f = ((_c = p.fields) != null ? _c : []).find(
|
|
@@ -6057,7 +6268,7 @@ var Editor = class {
|
|
|
6057
6268
|
* - Option: use placeOption() instead
|
|
6058
6269
|
*/
|
|
6059
6270
|
placeNode(id, opts) {
|
|
6060
|
-
if (isTagId(id)) {
|
|
6271
|
+
if (this.isTagId(id)) {
|
|
6061
6272
|
this.exec({
|
|
6062
6273
|
name: "placeTag",
|
|
6063
6274
|
do: () => this.patchProps((p) => {
|
|
@@ -6104,7 +6315,7 @@ var Editor = class {
|
|
|
6104
6315
|
}),
|
|
6105
6316
|
undo: () => this.api.undo()
|
|
6106
6317
|
});
|
|
6107
|
-
} else if (isFieldId(id)) {
|
|
6318
|
+
} else if (this.isFieldId(id)) {
|
|
6108
6319
|
if (!opts.scopeTagId)
|
|
6109
6320
|
throw new Error("placeNode(field): scopeTagId is required");
|
|
6110
6321
|
const fieldId = id;
|
|
@@ -6131,14 +6342,14 @@ var Editor = class {
|
|
|
6131
6342
|
}),
|
|
6132
6343
|
undo: () => this.api.undo()
|
|
6133
6344
|
});
|
|
6134
|
-
} else if (isOptionId(id)) {
|
|
6345
|
+
} else if (this.isOptionId(id)) {
|
|
6135
6346
|
this.placeOption(id, opts);
|
|
6136
6347
|
} else {
|
|
6137
6348
|
throw new Error("placeNode: unknown id prefix");
|
|
6138
6349
|
}
|
|
6139
6350
|
}
|
|
6140
6351
|
placeOption(optionId, opts) {
|
|
6141
|
-
if (!isOptionId(optionId))
|
|
6352
|
+
if (!this.isOptionId(optionId))
|
|
6142
6353
|
throw new Error('placeOption: optionId must start with "o:"');
|
|
6143
6354
|
this.exec({
|
|
6144
6355
|
name: "placeOption",
|
|
@@ -6195,7 +6406,7 @@ var Editor = class {
|
|
|
6195
6406
|
return id;
|
|
6196
6407
|
}
|
|
6197
6408
|
updateOption(optionId, patch) {
|
|
6198
|
-
if (!isOptionId(optionId))
|
|
6409
|
+
if (!this.isOptionId(optionId))
|
|
6199
6410
|
throw new Error('updateOption: optionId must start with "o:"');
|
|
6200
6411
|
this.exec({
|
|
6201
6412
|
name: "updateOption",
|
|
@@ -6214,7 +6425,7 @@ var Editor = class {
|
|
|
6214
6425
|
});
|
|
6215
6426
|
}
|
|
6216
6427
|
removeOption(optionId) {
|
|
6217
|
-
if (!isOptionId(optionId))
|
|
6428
|
+
if (!this.isOptionId(optionId))
|
|
6218
6429
|
throw new Error('removeOption: optionId must start with "o:"');
|
|
6219
6430
|
this.exec({
|
|
6220
6431
|
name: "removeOption",
|
|
@@ -6245,17 +6456,17 @@ var Editor = class {
|
|
|
6245
6456
|
name: "editLabel",
|
|
6246
6457
|
do: () => this.patchProps((p) => {
|
|
6247
6458
|
var _a, _b, _c, _d;
|
|
6248
|
-
if (isTagId(id)) {
|
|
6459
|
+
if (this.isTagId(id)) {
|
|
6249
6460
|
const t = ((_a = p.filters) != null ? _a : []).find((x) => x.id === id);
|
|
6250
6461
|
if (t) t.label = next;
|
|
6251
6462
|
return;
|
|
6252
6463
|
}
|
|
6253
|
-
if (isFieldId(id)) {
|
|
6464
|
+
if (this.isFieldId(id)) {
|
|
6254
6465
|
const f = ((_b = p.fields) != null ? _b : []).find((x) => x.id === id);
|
|
6255
6466
|
if (f) f.label = next;
|
|
6256
6467
|
return;
|
|
6257
6468
|
}
|
|
6258
|
-
if (isOptionId(id)) {
|
|
6469
|
+
if (this.isOptionId(id)) {
|
|
6259
6470
|
const own = ownerOfOption(p, id);
|
|
6260
6471
|
if (!own) return;
|
|
6261
6472
|
const f = ((_c = p.fields) != null ? _c : []).find(
|
|
@@ -6294,7 +6505,7 @@ var Editor = class {
|
|
|
6294
6505
|
const validId = hasSidKey && typeof input.service_id === "number" && Number.isFinite(input.service_id);
|
|
6295
6506
|
const sid = validId ? Number(input.service_id) : void 0;
|
|
6296
6507
|
const nextRole = input.pricing_role;
|
|
6297
|
-
if (isTagId(id)) {
|
|
6508
|
+
if (this.isTagId(id)) {
|
|
6298
6509
|
const t = ((_a = p.filters) != null ? _a : []).find((x) => x.id === id);
|
|
6299
6510
|
if (!t) return;
|
|
6300
6511
|
if (hasSidKey) {
|
|
@@ -6303,7 +6514,7 @@ var Editor = class {
|
|
|
6303
6514
|
}
|
|
6304
6515
|
return;
|
|
6305
6516
|
}
|
|
6306
|
-
if (isOptionId(id)) {
|
|
6517
|
+
if (this.isOptionId(id)) {
|
|
6307
6518
|
const own = ownerOfOption(p, id);
|
|
6308
6519
|
if (!own) return;
|
|
6309
6520
|
const f2 = ((_b = p.fields) != null ? _b : []).find(
|
|
@@ -6510,7 +6721,7 @@ var Editor = class {
|
|
|
6510
6721
|
});
|
|
6511
6722
|
}
|
|
6512
6723
|
remove(id) {
|
|
6513
|
-
if (isTagId(id)) {
|
|
6724
|
+
if (this.isTagId(id)) {
|
|
6514
6725
|
this.exec({
|
|
6515
6726
|
name: "removeTag",
|
|
6516
6727
|
do: () => this.patchProps((p) => {
|
|
@@ -6550,7 +6761,7 @@ var Editor = class {
|
|
|
6550
6761
|
});
|
|
6551
6762
|
return;
|
|
6552
6763
|
}
|
|
6553
|
-
if (isFieldId(id)) {
|
|
6764
|
+
if (this.isFieldId(id)) {
|
|
6554
6765
|
this.exec({
|
|
6555
6766
|
name: "removeField",
|
|
6556
6767
|
do: () => this.patchProps((p) => {
|
|
@@ -6586,7 +6797,7 @@ var Editor = class {
|
|
|
6586
6797
|
});
|
|
6587
6798
|
return;
|
|
6588
6799
|
}
|
|
6589
|
-
if (isOptionId(id)) {
|
|
6800
|
+
if (this.isOptionId(id)) {
|
|
6590
6801
|
this.removeOption(id);
|
|
6591
6802
|
return;
|
|
6592
6803
|
}
|
|
@@ -6595,7 +6806,7 @@ var Editor = class {
|
|
|
6595
6806
|
getNode(id) {
|
|
6596
6807
|
var _a, _b, _c, _d;
|
|
6597
6808
|
const props = this.builder.getProps();
|
|
6598
|
-
if (isTagId(id)) {
|
|
6809
|
+
if (this.isTagId(id)) {
|
|
6599
6810
|
const t = ((_a = props.filters) != null ? _a : []).find((x) => x.id === id);
|
|
6600
6811
|
return {
|
|
6601
6812
|
kind: "tag",
|
|
@@ -6603,12 +6814,12 @@ var Editor = class {
|
|
|
6603
6814
|
owners: { parentTagId: t == null ? void 0 : t.bind_id }
|
|
6604
6815
|
};
|
|
6605
6816
|
}
|
|
6606
|
-
if (isFieldId(id)) {
|
|
6817
|
+
if (this.isFieldId(id)) {
|
|
6607
6818
|
const f = ((_b = props.fields) != null ? _b : []).find((x) => x.id === id);
|
|
6608
6819
|
const bind = Array.isArray(f == null ? void 0 : f.bind_id) ? f.bind_id : (f == null ? void 0 : f.bind_id) ? [f.bind_id] : [];
|
|
6609
6820
|
return { kind: "field", data: f, owners: { bindTagIds: bind } };
|
|
6610
6821
|
}
|
|
6611
|
-
if (isOptionId(id)) {
|
|
6822
|
+
if (this.isOptionId(id)) {
|
|
6612
6823
|
const own = ownerOfOption(props, id);
|
|
6613
6824
|
const f = own ? ((_c = props.fields) != null ? _c : []).find((x) => x.id === own.fieldId) : void 0;
|
|
6614
6825
|
const o = (_d = f == null ? void 0 : f.options) == null ? void 0 : _d.find((x) => x.id === id);
|
|
@@ -6686,7 +6897,7 @@ var Editor = class {
|
|
|
6686
6897
|
if (receiverId === targetId) return true;
|
|
6687
6898
|
const getDirectRelations = (id) => {
|
|
6688
6899
|
var _a, _b, _c, _d, _e, _f, _g;
|
|
6689
|
-
if (isTagId(id)) {
|
|
6900
|
+
if (this.isTagId(id)) {
|
|
6690
6901
|
const t = ((_a = p.filters) != null ? _a : []).find((x) => x.id === id);
|
|
6691
6902
|
return [...(_b = t == null ? void 0 : t.includes) != null ? _b : [], ...(_c = t == null ? void 0 : t.excludes) != null ? _c : []];
|
|
6692
6903
|
}
|
|
@@ -6906,7 +7117,7 @@ var Editor = class {
|
|
|
6906
7117
|
do: () => this.patchProps((p) => {
|
|
6907
7118
|
var _a, _b, _c, _d, _e;
|
|
6908
7119
|
if (kind === "bind") {
|
|
6909
|
-
if (isTagId(fromId) && isTagId(toId2)) {
|
|
7120
|
+
if (this.isTagId(fromId) && this.isTagId(toId2)) {
|
|
6910
7121
|
if (this.wouldCreateTagCycle(p, fromId, toId2)) {
|
|
6911
7122
|
throw new Error(
|
|
6912
7123
|
`bind would create a cycle: ${fromId} \u2192 ${toId2}`
|
|
@@ -6918,9 +7129,9 @@ var Editor = class {
|
|
|
6918
7129
|
if (child) child.bind_id = fromId;
|
|
6919
7130
|
return;
|
|
6920
7131
|
}
|
|
6921
|
-
if (isTagId(fromId) && isFieldId(toId2) || isFieldId(fromId) && isTagId(toId2)) {
|
|
6922
|
-
const fieldId = isFieldId(toId2) ? toId2 : fromId;
|
|
6923
|
-
const tagId = isTagId(fromId) ? fromId : toId2;
|
|
7132
|
+
if (this.isTagId(fromId) && this.isFieldId(toId2) || this.isFieldId(fromId) && this.isTagId(toId2)) {
|
|
7133
|
+
const fieldId = this.isFieldId(toId2) ? toId2 : fromId;
|
|
7134
|
+
const tagId = this.isTagId(fromId) ? fromId : toId2;
|
|
6924
7135
|
const f = ((_b = p.fields) != null ? _b : []).find(
|
|
6925
7136
|
(x) => x.id === fieldId
|
|
6926
7137
|
);
|
|
@@ -6944,7 +7155,7 @@ var Editor = class {
|
|
|
6944
7155
|
}
|
|
6945
7156
|
if (kind === "include" || kind === "exclude") {
|
|
6946
7157
|
const key = kind === "include" ? "includes" : "excludes";
|
|
6947
|
-
if (isTagId(fromId) && isFieldId(toId2)) {
|
|
7158
|
+
if (this.isTagId(fromId) && this.isFieldId(toId2)) {
|
|
6948
7159
|
const t = ((_c = p.filters) != null ? _c : []).find(
|
|
6949
7160
|
(x) => x.id === fromId
|
|
6950
7161
|
);
|
|
@@ -6953,7 +7164,7 @@ var Editor = class {
|
|
|
6953
7164
|
if (!arr.includes(toId2)) arr.push(toId2);
|
|
6954
7165
|
return;
|
|
6955
7166
|
}
|
|
6956
|
-
if (isOptionId(fromId) && isFieldId(toId2)) {
|
|
7167
|
+
if (this.isOptionId(fromId) && this.isFieldId(toId2)) {
|
|
6957
7168
|
const mapKey = kind === "include" ? "includes_for_options" : "excludes_for_options";
|
|
6958
7169
|
const maps = p[mapKey];
|
|
6959
7170
|
const next = { ...maps != null ? maps : {} };
|
|
@@ -7021,16 +7232,16 @@ var Editor = class {
|
|
|
7021
7232
|
do: () => this.patchProps((p) => {
|
|
7022
7233
|
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
7023
7234
|
if (kind === "bind") {
|
|
7024
|
-
if (isTagId(fromId) && isTagId(toId2)) {
|
|
7235
|
+
if (this.isTagId(fromId) && this.isTagId(toId2)) {
|
|
7025
7236
|
const child = ((_a = p.filters) != null ? _a : []).find(
|
|
7026
7237
|
(t) => t.id === toId2
|
|
7027
7238
|
);
|
|
7028
7239
|
if ((child == null ? void 0 : child.bind_id) === fromId) delete child.bind_id;
|
|
7029
7240
|
return;
|
|
7030
7241
|
}
|
|
7031
|
-
if (isTagId(fromId) && isFieldId(toId2) || isFieldId(fromId) && isTagId(toId2)) {
|
|
7032
|
-
const fieldId = isFieldId(toId2) ? toId2 : fromId;
|
|
7033
|
-
const tagId = isTagId(fromId) ? fromId : toId2;
|
|
7242
|
+
if (this.isTagId(fromId) && this.isFieldId(toId2) || this.isFieldId(fromId) && this.isTagId(toId2)) {
|
|
7243
|
+
const fieldId = this.isFieldId(toId2) ? toId2 : fromId;
|
|
7244
|
+
const tagId = this.isTagId(fromId) ? fromId : toId2;
|
|
7034
7245
|
const f = ((_b = p.fields) != null ? _b : []).find(
|
|
7035
7246
|
(x) => x.id === fieldId
|
|
7036
7247
|
);
|
|
@@ -7051,7 +7262,7 @@ var Editor = class {
|
|
|
7051
7262
|
}
|
|
7052
7263
|
if (kind === "include" || kind === "exclude") {
|
|
7053
7264
|
const key = kind === "include" ? "includes" : "excludes";
|
|
7054
|
-
if (isTagId(fromId) && isFieldId(toId2)) {
|
|
7265
|
+
if (this.isTagId(fromId) && this.isFieldId(toId2)) {
|
|
7055
7266
|
const t = ((_d = p.filters) != null ? _d : []).find(
|
|
7056
7267
|
(x) => x.id === fromId
|
|
7057
7268
|
);
|
|
@@ -7060,7 +7271,7 @@ var Editor = class {
|
|
|
7060
7271
|
if (!((_f = t[key]) == null ? void 0 : _f.length)) delete t[key];
|
|
7061
7272
|
return;
|
|
7062
7273
|
}
|
|
7063
|
-
if (isOptionId(fromId) && isFieldId(toId2)) {
|
|
7274
|
+
if (this.isOptionId(fromId) && this.isFieldId(toId2)) {
|
|
7064
7275
|
const mapKey = kind === "include" ? "includes_for_options" : "excludes_for_options";
|
|
7065
7276
|
const maps = p[mapKey];
|
|
7066
7277
|
if (!maps) return;
|
|
@@ -7527,8 +7738,6 @@ function toStrSet(v) {
|
|
|
7527
7738
|
}
|
|
7528
7739
|
|
|
7529
7740
|
// src/react/canvas/selection.ts
|
|
7530
|
-
var isTagId2 = (id) => typeof id === "string" && id.startsWith("t:");
|
|
7531
|
-
var isOptionId2 = (id) => typeof id === "string" && id.startsWith("o:");
|
|
7532
7741
|
var Selection = class {
|
|
7533
7742
|
constructor(builder, opts) {
|
|
7534
7743
|
this.builder = builder;
|
|
@@ -7600,7 +7809,7 @@ var Selection = class {
|
|
|
7600
7809
|
var _a;
|
|
7601
7810
|
const props = this.builder.getProps();
|
|
7602
7811
|
if (((_a = this.opts.env) != null ? _a : "client") === "workspace") {
|
|
7603
|
-
const tagIds = Array.from(this.set).filter(
|
|
7812
|
+
const tagIds = Array.from(this.set).filter(this.builder.isTagId.bind(this.builder));
|
|
7604
7813
|
if (tagIds.length > 1) {
|
|
7605
7814
|
return { kind: "multi", groups: Array.from(this.set) };
|
|
7606
7815
|
}
|
|
@@ -7633,7 +7842,7 @@ var Selection = class {
|
|
|
7633
7842
|
this.currentTagId = Array.isArray(f.bind_id) ? f.bind_id[0] : f.bind_id;
|
|
7634
7843
|
return;
|
|
7635
7844
|
}
|
|
7636
|
-
if (
|
|
7845
|
+
if (this.builder.isOptionId(id)) {
|
|
7637
7846
|
const host = fields.find(
|
|
7638
7847
|
(x) => {
|
|
7639
7848
|
var _a2;
|
|
@@ -7657,7 +7866,7 @@ var Selection = class {
|
|
|
7657
7866
|
resolveTagContextId(props) {
|
|
7658
7867
|
var _a;
|
|
7659
7868
|
if (this.currentTagId) return this.currentTagId;
|
|
7660
|
-
for (const id of this.set) if (
|
|
7869
|
+
for (const id of this.set) if (this.builder.isTagId(id)) return id;
|
|
7661
7870
|
const fields = (_a = props.fields) != null ? _a : [];
|
|
7662
7871
|
for (const id of this.set) {
|
|
7663
7872
|
const f = fields.find((x) => x.id === id);
|
|
@@ -7665,7 +7874,7 @@ var Selection = class {
|
|
|
7665
7874
|
return Array.isArray(f.bind_id) ? f.bind_id[0] : f.bind_id;
|
|
7666
7875
|
}
|
|
7667
7876
|
for (const id of this.set) {
|
|
7668
|
-
if (
|
|
7877
|
+
if (this.builder.isOptionId(id)) {
|
|
7669
7878
|
const host = fields.find(
|
|
7670
7879
|
(x) => {
|
|
7671
7880
|
var _a2;
|
|
@@ -7786,7 +7995,7 @@ var Selection = class {
|
|
|
7786
7995
|
}
|
|
7787
7996
|
findOptionById(fields, selId) {
|
|
7788
7997
|
var _a, _b;
|
|
7789
|
-
if (
|
|
7998
|
+
if (this.builder.isOptionId(selId)) {
|
|
7790
7999
|
for (const f of fields) {
|
|
7791
8000
|
const o = (_a = f.options) == null ? void 0 : _a.find((x) => x.id === selId);
|
|
7792
8001
|
if (o) return o;
|
|
@@ -8208,8 +8417,8 @@ function useCanvasOwned(initialProps, canvasOpts, builderOpts) {
|
|
|
8208
8417
|
// src/react/workspace/context/hooks/use-canvas.ts
|
|
8209
8418
|
import * as React16 from "react";
|
|
8210
8419
|
import { useMemo as useMemo15 } from "react";
|
|
8211
|
-
var
|
|
8212
|
-
var
|
|
8420
|
+
var isTagId = (id) => id.startsWith("t:");
|
|
8421
|
+
var isOptionId = (id) => id.startsWith("o:");
|
|
8213
8422
|
function deriveSelectionInfo(props, ids) {
|
|
8214
8423
|
var _a, _b, _c, _d;
|
|
8215
8424
|
const tags = [];
|
|
@@ -8218,11 +8427,11 @@ function deriveSelectionInfo(props, ids) {
|
|
|
8218
8427
|
const fieldById = /* @__PURE__ */ new Map();
|
|
8219
8428
|
for (const f of (_a = props.fields) != null ? _a : []) fieldById.set(f.id, f);
|
|
8220
8429
|
for (const id of ids) {
|
|
8221
|
-
if (
|
|
8430
|
+
if (isTagId(id)) {
|
|
8222
8431
|
tags.push(id);
|
|
8223
8432
|
continue;
|
|
8224
8433
|
}
|
|
8225
|
-
if (
|
|
8434
|
+
if (isOptionId(id)) {
|
|
8226
8435
|
options.push(id);
|
|
8227
8436
|
continue;
|
|
8228
8437
|
}
|