@timeax/digital-service-engine 0.0.2 → 0.0.3

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.
@@ -640,6 +640,7 @@ type OrderSnapshot = {
640
640
  builtAt: string;
641
641
  selection: {
642
642
  tag: string;
643
+ buttons: string[];
643
644
  fields: Array<{
644
645
  id: string;
645
646
  type: string;
@@ -640,6 +640,7 @@ type OrderSnapshot = {
640
640
  builtAt: string;
641
641
  selection: {
642
642
  tag: string;
643
+ buttons: string[];
643
644
  fields: Array<{
644
645
  id: string;
645
646
  type: string;
@@ -3500,13 +3500,10 @@ function visibleFieldIdsUnder(props, tagId, opts = {}) {
3500
3500
  if (order && order.length) {
3501
3501
  const ordered = order.filter((fid) => visible.has(fid));
3502
3502
  const orderedSet = new Set(ordered);
3503
- const rest2 = base.filter((fid) => !orderedSet.has(fid));
3504
- return [...ordered, ...rest2];
3503
+ const rest = base.filter((fid) => !orderedSet.has(fid));
3504
+ return [...ordered, ...rest];
3505
3505
  }
3506
- const promoted = revealedOrder.filter((fid) => visible.has(fid));
3507
- const promotedSet = new Set(promoted);
3508
- const rest = base.filter((fid) => !promotedSet.has(fid));
3509
- return [...promoted, ...rest];
3506
+ return base;
3510
3507
  }
3511
3508
  function visibleFieldsUnder(props, tagId, opts = {}) {
3512
3509
  var _a;
@@ -7798,6 +7795,7 @@ var Selection = class {
7798
7795
  this.emit();
7799
7796
  }
7800
7797
  add(id) {
7798
+ if (this.set.has(id)) this.set.delete(id);
7801
7799
  this.set.add(id);
7802
7800
  this.primaryId = id;
7803
7801
  this.updateCurrentTagFrom(id);
@@ -7852,7 +7850,9 @@ var Selection = class {
7852
7850
  var _a;
7853
7851
  const props = this.builder.getProps();
7854
7852
  if (((_a = this.opts.env) != null ? _a : "client") === "workspace") {
7855
- const tagIds = Array.from(this.set).filter(this.builder.isTagId.bind(this.builder));
7853
+ const tagIds = Array.from(this.set).filter(
7854
+ this.builder.isTagId.bind(this.builder)
7855
+ );
7856
7856
  if (tagIds.length > 1) {
7857
7857
  return { kind: "multi", groups: Array.from(this.set) };
7858
7858
  }
@@ -7863,6 +7863,98 @@ var Selection = class {
7863
7863
  const group = this.computeGroupForTag(props, tagId);
7864
7864
  return { kind: "single", group };
7865
7865
  }
7866
+ /**
7867
+ * Build a fieldId -> triggerKeys[] map from the current selection set.
7868
+ *
7869
+ * What counts as a "button selection" (trigger key):
7870
+ * - field key where the field has button === true (e.g. "f:dripfeed")
7871
+ * - option key (e.g. "o:fast")
7872
+ * - composite key "fieldId::optionId" (e.g. "f:speed::o:fast")
7873
+ *
7874
+ * Grouping:
7875
+ * - button-field trigger groups under its own fieldId
7876
+ * - option/composite groups under the option's owning fieldId (from nodeMap)
7877
+ *
7878
+ * Deterministic:
7879
+ * - preserves selection insertion order
7880
+ * - de-dupes per field
7881
+ */
7882
+ buttonSelectionsByFieldId() {
7883
+ var _a, _b, _c, _d, _e;
7884
+ const nodeMap = this.builder.getNodeMap();
7885
+ const out = {};
7886
+ const push = (fieldId, triggerKey) => {
7887
+ var _a2;
7888
+ const arr = (_a2 = out[fieldId]) != null ? _a2 : out[fieldId] = [];
7889
+ if (!arr.includes(triggerKey)) arr.push(triggerKey);
7890
+ };
7891
+ for (const key of this.set) {
7892
+ if (!key) continue;
7893
+ const idx = key.indexOf("::");
7894
+ if (idx !== -1) {
7895
+ const optionId = key.slice(idx + 2);
7896
+ const optRef = nodeMap.get(optionId);
7897
+ if ((optRef == null ? void 0 : optRef.kind) === "option" && typeof optRef.fieldId === "string") {
7898
+ push(optRef.fieldId, key);
7899
+ }
7900
+ continue;
7901
+ }
7902
+ const ref = nodeMap.get(key);
7903
+ if (!ref) continue;
7904
+ if (ref.kind === "option" && typeof ref.fieldId === "string") {
7905
+ push(ref.fieldId, (_a = ref.id) != null ? _a : key);
7906
+ continue;
7907
+ }
7908
+ if (ref.kind === "field") {
7909
+ const field = (_c = (_b = ref.node) != null ? _b : ref.field) != null ? _c : ref;
7910
+ const fieldId = (_e = (_d = ref.id) != null ? _d : field == null ? void 0 : field.id) != null ? _e : key;
7911
+ if ((field == null ? void 0 : field.button) === true && typeof fieldId === "string") {
7912
+ push(fieldId, fieldId);
7913
+ }
7914
+ }
7915
+ }
7916
+ return out;
7917
+ }
7918
+ /**
7919
+ * Returns only selection keys that are valid "trigger buttons":
7920
+ * - field keys where field.button === true
7921
+ * - option keys
7922
+ * - composite keys "fieldId::optionId" (validated by optionId)
7923
+ * Excludes tags and non-button fields.
7924
+ */
7925
+ selectedButtons() {
7926
+ var _a, _b;
7927
+ const nodeMap = this.builder.getNodeMap();
7928
+ const out = [];
7929
+ const seen = /* @__PURE__ */ new Set();
7930
+ const push = (k) => {
7931
+ if (!seen.has(k)) {
7932
+ seen.add(k);
7933
+ out.push(k);
7934
+ }
7935
+ };
7936
+ for (const key of this.set) {
7937
+ if (!key) continue;
7938
+ const idx = key.indexOf("::");
7939
+ if (idx !== -1) {
7940
+ const optionId = key.slice(idx + 2);
7941
+ const optRef = nodeMap.get(optionId);
7942
+ if ((optRef == null ? void 0 : optRef.kind) === "option") push(key);
7943
+ continue;
7944
+ }
7945
+ const ref = nodeMap.get(key);
7946
+ if (!ref) continue;
7947
+ if (ref.kind === "option") {
7948
+ push(key);
7949
+ continue;
7950
+ }
7951
+ if (ref.kind === "field") {
7952
+ const field = (_b = (_a = ref.node) != null ? _a : ref.field) != null ? _b : ref;
7953
+ if ((field == null ? void 0 : field.button) === true) push(key);
7954
+ }
7955
+ }
7956
+ return out;
7957
+ }
7866
7958
  // ── Internals ────────────────────────────────────────────────────────────
7867
7959
  emit() {
7868
7960
  const payload = {
@@ -7936,28 +8028,13 @@ var Selection = class {
7936
8028
  }
7937
8029
  return this.opts.rootTagId;
7938
8030
  }
7939
- selectedButtonTriggerIds(props) {
7940
- var _a;
7941
- const fields = (_a = props.fields) != null ? _a : [];
7942
- const fieldById = new Map(fields.map((f) => [f.id, f]));
7943
- const out = [];
7944
- for (const selId of this.set) {
7945
- if (selId.startsWith("o:")) {
7946
- out.push(selId);
7947
- continue;
7948
- }
7949
- const f = fieldById.get(selId);
7950
- if ((f == null ? void 0 : f.button) === true) out.push(selId);
7951
- }
7952
- return out;
7953
- }
7954
8031
  computeGroupForTag(props, tagId) {
7955
8032
  var _a, _b, _c, _d, _e, _f, _g;
7956
8033
  const tags = (_a = props.filters) != null ? _a : [];
7957
8034
  const fields = (_b = props.fields) != null ? _b : [];
7958
8035
  const tagById = new Map(tags.map((t) => [t.id, t]));
7959
8036
  const tag = tagById.get(tagId);
7960
- const selectedTriggerIds = this.selectedButtonTriggerIds(props);
8037
+ const selectedTriggerIds = this.selectedButtons();
7961
8038
  const fieldIds = this.builder.visibleFields(tagId, selectedTriggerIds);
7962
8039
  const fieldById = new Map(fields.map((f) => [f.id, f]));
7963
8040
  const visible = fieldIds.map((id) => fieldById.get(id)).filter(Boolean);