spytial-core 1.4.10 → 1.4.11-beta.1

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.
@@ -94528,7 +94528,6 @@ VVbdfjptxz|~\x80\x82\x84\xA6\xA8W\b
94528
94528
  init_layoutinstance();
94529
94529
  init_layoutspec();
94530
94530
  exports.StructuredInputGraph = class extends WebColaCnDGraph {
94531
- // Default to 2 positions
94532
94531
  constructor(dataInstance) {
94533
94532
  super();
94534
94533
  this.evaluator = null;
@@ -94537,6 +94536,16 @@ VVbdfjptxz|~\x80\x82\x84\xA6\xA8W\b
94537
94536
  this.controlsContainer = null;
94538
94537
  this.customTypes = /* @__PURE__ */ new Set();
94539
94538
  this.relationAtomPositions = ["", ""];
94539
+ // Default to 2 positions
94540
+ this.currentConstraintError = null;
94541
+ // Track current constraint validation error
94542
+ // Track event listeners to prevent duplicates
94543
+ this.dataInstanceEventHandlers = {
94544
+ atomAdded: null,
94545
+ atomRemoved: null,
94546
+ relationTupleAdded: null,
94547
+ relationTupleRemoved: null
94548
+ };
94540
94549
  const instance = dataInstance || new exports.JSONDataInstance({
94541
94550
  atoms: [],
94542
94551
  relations: []
@@ -95217,6 +95226,7 @@ VVbdfjptxz|~\x80\x82\x84\xA6\xA8W\b
95217
95226
  }
95218
95227
  /**
95219
95228
  * Enforce constraints and regenerate layout
95229
+ * This method validates constraints on every data update and reports UNSAT cores
95220
95230
  */
95221
95231
  async enforceConstraintsAndRegenerate() {
95222
95232
  console.log("\u{1F504} enforceConstraintsAndRegenerate() called");
@@ -95240,15 +95250,37 @@ VVbdfjptxz|~\x80\x82\x84\xA6\xA8W\b
95240
95250
  const projections = {};
95241
95251
  const layoutResult = this.layoutInstance.generateLayout(this.dataInstance, projections);
95242
95252
  if (layoutResult.error) {
95243
- console.warn("\u26A0\uFE0F Constraint validation error:", layoutResult.error);
95253
+ console.warn("\u26A0\uFE0F Constraint validation error detected:", layoutResult.error);
95254
+ this.currentConstraintError = layoutResult.error;
95255
+ this.dispatchEvent(new CustomEvent("constraint-error", {
95256
+ detail: {
95257
+ error: layoutResult.error,
95258
+ layout: layoutResult.layout
95259
+ },
95260
+ bubbles: true
95261
+ }));
95262
+ console.log("\u{1F4E4} Dispatched constraint-error event with UNSAT core information");
95244
95263
  } else {
95245
- console.log("\u2705 Layout generated successfully");
95264
+ console.log("\u2705 Layout generated successfully - all constraints satisfied");
95265
+ if (this.currentConstraintError !== null) {
95266
+ console.log("\u{1F9F9} Clearing previous constraint error - constraints now satisfied");
95267
+ this.currentConstraintError = null;
95268
+ this.dispatchEvent(new CustomEvent("constraints-satisfied", {
95269
+ detail: { layout: layoutResult.layout },
95270
+ bubbles: true
95271
+ }));
95272
+ console.log("\u{1F4E4} Dispatched constraints-satisfied event");
95273
+ }
95246
95274
  }
95247
95275
  console.log("\u{1F3A8} Rendering layout...");
95248
95276
  await this.renderLayout(layoutResult.layout);
95249
95277
  console.log("\u2705 Constraints enforced and layout regenerated successfully");
95250
95278
  } catch (error) {
95251
95279
  console.error("\u274C Failed to enforce constraints and regenerate layout:", error);
95280
+ this.dispatchEvent(new CustomEvent("layout-generation-error", {
95281
+ detail: { error },
95282
+ bubbles: true
95283
+ }));
95252
95284
  }
95253
95285
  }
95254
95286
  /**
@@ -95507,24 +95539,66 @@ VVbdfjptxz|~\x80\x82\x84\xA6\xA8W\b
95507
95539
  console.error("\u274C Failed to export data:", error);
95508
95540
  }
95509
95541
  }
95542
+ /**
95543
+ * Common handler for data changes that updates UI components
95544
+ * @param includeAtomPositions - Whether to update atom position selectors (needed for atom changes)
95545
+ */
95546
+ handleDataChangeUIUpdate(includeAtomPositions = false) {
95547
+ this.refreshTypesFromDataInstance();
95548
+ this.updateDeletionSelects();
95549
+ if (includeAtomPositions) {
95550
+ this.updateAtomPositions();
95551
+ }
95552
+ }
95553
+ /**
95554
+ * Common handler for data deletions that updates UI and triggers constraint validation
95555
+ * @param includeAtomPositions - Whether to update atom position selectors (needed for atom deletions)
95556
+ */
95557
+ async handleDataDeletionWithValidation(includeAtomPositions = false) {
95558
+ this.handleDataChangeUIUpdate(includeAtomPositions);
95559
+ await this.enforceConstraintsAndRegenerate();
95560
+ }
95510
95561
  /**
95511
95562
  * Set the data instance for this graph
95512
95563
  */
95513
95564
  setDataInstance(instance) {
95514
95565
  console.log("\u{1F504} Setting new data instance");
95566
+ if (this.dataInstance) {
95567
+ if (this.dataInstanceEventHandlers.atomAdded) {
95568
+ this.dataInstance.removeEventListener("atomAdded", this.dataInstanceEventHandlers.atomAdded);
95569
+ }
95570
+ if (this.dataInstanceEventHandlers.atomRemoved) {
95571
+ this.dataInstance.removeEventListener("atomRemoved", this.dataInstanceEventHandlers.atomRemoved);
95572
+ }
95573
+ if (this.dataInstanceEventHandlers.relationTupleAdded) {
95574
+ this.dataInstance.removeEventListener("relationTupleAdded", this.dataInstanceEventHandlers.relationTupleAdded);
95575
+ }
95576
+ if (this.dataInstanceEventHandlers.relationTupleRemoved) {
95577
+ this.dataInstance.removeEventListener("relationTupleRemoved", this.dataInstanceEventHandlers.relationTupleRemoved);
95578
+ }
95579
+ }
95515
95580
  this.dataInstance = instance;
95516
95581
  this.refreshTypesFromDataInstance();
95517
- instance.addEventListener("atomAdded", () => {
95582
+ this.dataInstanceEventHandlers.atomAdded = () => {
95518
95583
  console.log("\u{1F4CD} Atom added to instance - updating UI");
95519
- this.refreshTypesFromDataInstance();
95520
- this.updateDeletionSelects();
95521
- this.updateAtomPositions();
95522
- });
95523
- instance.addEventListener("relationTupleAdded", () => {
95584
+ this.handleDataChangeUIUpdate(true);
95585
+ };
95586
+ this.dataInstanceEventHandlers.relationTupleAdded = () => {
95524
95587
  console.log("\u{1F517} Relation added to instance - updating UI");
95525
- this.refreshTypesFromDataInstance();
95526
- this.updateDeletionSelects();
95527
- });
95588
+ this.handleDataChangeUIUpdate(false);
95589
+ };
95590
+ this.dataInstanceEventHandlers.atomRemoved = async () => {
95591
+ console.log("\u{1F5D1}\uFE0F Atom removed from instance - updating UI and re-validating constraints");
95592
+ await this.handleDataDeletionWithValidation(true);
95593
+ };
95594
+ this.dataInstanceEventHandlers.relationTupleRemoved = async () => {
95595
+ console.log("\u{1F5D1}\uFE0F Relation tuple removed from instance - updating UI and re-validating constraints");
95596
+ await this.handleDataDeletionWithValidation(false);
95597
+ };
95598
+ instance.addEventListener("atomAdded", this.dataInstanceEventHandlers.atomAdded);
95599
+ instance.addEventListener("relationTupleAdded", this.dataInstanceEventHandlers.relationTupleAdded);
95600
+ instance.addEventListener("atomRemoved", this.dataInstanceEventHandlers.atomRemoved);
95601
+ instance.addEventListener("relationTupleRemoved", this.dataInstanceEventHandlers.relationTupleRemoved);
95528
95602
  this.updateDeletionSelects();
95529
95603
  this.updateAtomPositions();
95530
95604
  console.log("\u2705 Data instance set successfully");
@@ -95583,18 +95657,8 @@ VVbdfjptxz|~\x80\x82\x84\xA6\xA8W\b
95583
95657
  console.warn(`\u26A0\uFE0F Atom ${atomId} not found`);
95584
95658
  return;
95585
95659
  }
95586
- const remainingAtoms = atoms.filter((atom) => atom.id !== atomId);
95587
- const relations = this.dataInstance.getRelations().filter(
95588
- (rel) => !rel.tuples.some((tuple) => tuple.atoms.includes(atomId))
95589
- );
95590
- const newInstance = new exports.JSONDataInstance({
95591
- atoms: remainingAtoms,
95592
- relations,
95593
- types: []
95594
- });
95595
- this.setDataInstance(newInstance);
95660
+ this.dataInstance.removeAtom(atomId);
95596
95661
  console.log(`\u2705 Atom removed from data instance: ${atomToDelete.label} (${atomToDelete.id})`);
95597
- await this.enforceConstraintsAndRegenerate();
95598
95662
  console.log(`\u{1F389} Atom deletion completed: ${atomToDelete.label} (${atomToDelete.id})`);
95599
95663
  this.dispatchEvent(new CustomEvent("atom-deleted", {
95600
95664
  detail: { atom: atomToDelete }
@@ -95634,9 +95698,7 @@ VVbdfjptxz|~\x80\x82\x84\xA6\xA8W\b
95634
95698
  console.log(`\u{1F5D1}\uFE0F Found tuple in relation "${relationId}": ${targetTuple.atoms.join(" \u2192 ")}`);
95635
95699
  this.dataInstance.removeRelationTuple(relationId, targetTuple);
95636
95700
  console.log(`\u2705 Relation tuple removed from data instance: ${relationId}: ${targetTuple.atoms.join(" \u2192 ")}`);
95637
- await this.enforceConstraintsAndRegenerate();
95638
95701
  console.log(`\u{1F389} Relation tuple deletion completed: ${relationId}: ${targetTuple.atoms.join(" \u2192 ")}`);
95639
- this.updateDeletionSelects();
95640
95702
  this.dispatchEvent(new CustomEvent("relation-tuple-deleted", {
95641
95703
  detail: { relationId, tuple: targetTuple }
95642
95704
  }));
@@ -95672,6 +95734,19 @@ VVbdfjptxz|~\x80\x82\x84\xA6\xA8W\b
95672
95734
  getDataInstance() {
95673
95735
  return this.dataInstance;
95674
95736
  }
95737
+ /**
95738
+ * Get the current constraint error (if any)
95739
+ * Returns null if all constraints are currently satisfied
95740
+ */
95741
+ getCurrentConstraintError() {
95742
+ return this.currentConstraintError;
95743
+ }
95744
+ /**
95745
+ * Check if there are currently unsatisfied constraints
95746
+ */
95747
+ hasConstraintErrors() {
95748
+ return this.currentConstraintError !== null;
95749
+ }
95675
95750
  /**
95676
95751
  * Set the CnD specification
95677
95752
  */