holosphere 1.3.0-alpha8 → 1.3.0-alpha9

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/federation.js CHANGED
@@ -4,7 +4,7 @@
4
4
  */
5
5
 
6
6
  import * as h3 from 'h3-js';
7
- import { attachHologramMeta } from './hologram.js';
7
+ import { attachHologramMeta, parseSoulPath } from './hologram.js';
8
8
 
9
9
  /**
10
10
  * Look up a holon's display name from its `settings` lens.
@@ -887,11 +887,32 @@ export async function propagate(holosphere, holon, lens, data, options = {}) {
887
887
  };
888
888
  }
889
889
 
890
- // Defensive: even if the outbound list somehow
891
- // contains the source holon, never write a self-
892
- // hologram. The source already has the original.
893
- if (String(targetSpace) === String(holon)) {
890
+ // Never write a hologram to the holon its soul
891
+ // already points at that overwrites the original
892
+ // record with a pointer to itself (a circular
893
+ // hologram that can never resolve, so get() logs
894
+ // "CIRCULAR … Breaking loop" forever). Two cases:
895
+ // • target === source: the source already holds
896
+ // the original; don't self-hologram it.
897
+ // • forwarding a RECEIVED hologram back toward its
898
+ // birthplace via a third hop (A→B propagates,
899
+ // then B→A federation echoes the hologram — whose
900
+ // soul still points at A — home). The plain
901
+ // `target === holon` check misses this because
902
+ // here `holon` is B, not A.
903
+ const soulTargetHolon =
904
+ payloadToPut && typeof payloadToPut.soul === 'string'
905
+ ? parseSoulPath(payloadToPut.soul)?.holon
906
+ : null;
907
+ if (
908
+ String(targetSpace) === String(holon) ||
909
+ (soulTargetHolon != null &&
910
+ String(soulTargetHolon) === String(targetSpace))
911
+ ) {
894
912
  result.skipped++;
913
+ result.messages.push(
914
+ `Skipped self-referential propagation of ${data.id} to ${targetSpace} (hologram soul already points there).`
915
+ );
895
916
  return true;
896
917
  }
897
918
 
@@ -1018,10 +1039,31 @@ export async function propagate(holosphere, holon, lens, data, options = {}) {
1018
1039
  };
1019
1040
  }
1020
1041
 
1042
+ // Same self-reference guard as partner
1043
+ // propagation: never write a hologram to the
1044
+ // holon its soul points at (would create a
1045
+ // circular self-pointer that can never resolve).
1046
+ const soulTargetHolonParent =
1047
+ payloadToPut && typeof payloadToPut.soul === 'string'
1048
+ ? parseSoulPath(payloadToPut.soul)?.holon
1049
+ : null;
1050
+ if (
1051
+ String(parentHexagon) === String(holon) ||
1052
+ (soulTargetHolonParent != null &&
1053
+ String(soulTargetHolonParent) === String(parentHexagon))
1054
+ ) {
1055
+ result.parentPropagation.skipped =
1056
+ (result.parentPropagation.skipped || 0) + 1;
1057
+ result.parentPropagation.messages.push(
1058
+ `Skipped self-referential parent propagation of ${data.id} to ${parentHexagon} (hologram soul already points there).`
1059
+ );
1060
+ return true;
1061
+ }
1062
+
1021
1063
  // Store in the parent hexagon with redirection disabled and no further auto-propagation
1022
- await holosphere.put(parentHexagon, lens, payloadToPut, null, {
1023
- disableHologramRedirection: true,
1024
- autoPropagate: false
1064
+ await holosphere.put(parentHexagon, lens, payloadToPut, null, {
1065
+ disableHologramRedirection: true,
1066
+ autoPropagate: false
1025
1067
  });
1026
1068
 
1027
1069
  console.log(`[Federation] Successfully propagated to parent hexagon: ${parentHexagon}`);
@@ -1,9 +1,9 @@
1
1
  /**
2
- * HoloSphere ESM Bundle v1.3.0-alpha8
2
+ * HoloSphere ESM Bundle v1.3.0-alpha9
3
3
  * ES6 Module version with all dependencies bundled
4
4
  *
5
5
  * Usage:
6
- * import HoloSphere from 'https://unpkg.com/holosphere@1.3.0-alpha8/holosphere-bundle.esm.js';
6
+ * import HoloSphere from 'https://unpkg.com/holosphere@1.3.0-alpha9/holosphere-bundle.esm.js';
7
7
  * const hs = new HoloSphere('myapp');
8
8
  */
9
9
  var __create = Object.create;
@@ -25018,8 +25018,12 @@ async function propagate(holosphere, holon, lens, data, options = {}) {
25018
25018
  }
25019
25019
  };
25020
25020
  }
25021
- if (String(targetSpace) === String(holon)) {
25021
+ const soulTargetHolon = payloadToPut && typeof payloadToPut.soul === "string" ? parseSoulPath(payloadToPut.soul)?.holon : null;
25022
+ if (String(targetSpace) === String(holon) || soulTargetHolon != null && String(soulTargetHolon) === String(targetSpace)) {
25022
25023
  result.skipped++;
25024
+ result.messages.push(
25025
+ `Skipped self-referential propagation of ${data.id} to ${targetSpace} (hologram soul already points there).`
25026
+ );
25023
25027
  return true;
25024
25028
  }
25025
25029
  await holosphere.put(targetSpace, lens, payloadToPut, null, {
@@ -25122,6 +25126,14 @@ async function propagate(holosphere, holon, lens, data, options = {}) {
25122
25126
  }
25123
25127
  };
25124
25128
  }
25129
+ const soulTargetHolonParent = payloadToPut && typeof payloadToPut.soul === "string" ? parseSoulPath(payloadToPut.soul)?.holon : null;
25130
+ if (String(parentHexagon) === String(holon) || soulTargetHolonParent != null && String(soulTargetHolonParent) === String(parentHexagon)) {
25131
+ result.parentPropagation.skipped = (result.parentPropagation.skipped || 0) + 1;
25132
+ result.parentPropagation.messages.push(
25133
+ `Skipped self-referential parent propagation of ${data.id} to ${parentHexagon} (hologram soul already points there).`
25134
+ );
25135
+ return true;
25136
+ }
25125
25137
  await holosphere.put(parentHexagon, lens, payloadToPut, null, {
25126
25138
  disableHologramRedirection: true,
25127
25139
  autoPropagate: false
@@ -1,5 +1,5 @@
1
1
  /**
2
- * HoloSphere Bundle v1.3.0-alpha8
2
+ * HoloSphere Bundle v1.3.0-alpha9
3
3
  * Holonic Geospatial Communication Infrastructure
4
4
  *
5
5
  * Includes:
@@ -9,7 +9,7 @@
9
9
  * - Ajv (JSON schema validation)
10
10
  *
11
11
  * Usage:
12
- * <script src="https://unpkg.com/holosphere@1.3.0-alpha8/holosphere-bundle.js"></script>
12
+ * <script src="https://unpkg.com/holosphere@1.3.0-alpha9/holosphere-bundle.js"></script>
13
13
  * <script>
14
14
  * const hs = new HoloSphere('myapp');
15
15
  * </script>
@@ -25044,8 +25044,12 @@ var HoloSphere = (() => {
25044
25044
  }
25045
25045
  };
25046
25046
  }
25047
- if (String(targetSpace) === String(holon)) {
25047
+ const soulTargetHolon = payloadToPut && typeof payloadToPut.soul === "string" ? parseSoulPath(payloadToPut.soul)?.holon : null;
25048
+ if (String(targetSpace) === String(holon) || soulTargetHolon != null && String(soulTargetHolon) === String(targetSpace)) {
25048
25049
  result.skipped++;
25050
+ result.messages.push(
25051
+ `Skipped self-referential propagation of ${data.id} to ${targetSpace} (hologram soul already points there).`
25052
+ );
25049
25053
  return true;
25050
25054
  }
25051
25055
  await holosphere.put(targetSpace, lens, payloadToPut, null, {
@@ -25148,6 +25152,14 @@ var HoloSphere = (() => {
25148
25152
  }
25149
25153
  };
25150
25154
  }
25155
+ const soulTargetHolonParent = payloadToPut && typeof payloadToPut.soul === "string" ? parseSoulPath(payloadToPut.soul)?.holon : null;
25156
+ if (String(parentHexagon) === String(holon) || soulTargetHolonParent != null && String(soulTargetHolonParent) === String(parentHexagon)) {
25157
+ result.parentPropagation.skipped = (result.parentPropagation.skipped || 0) + 1;
25158
+ result.parentPropagation.messages.push(
25159
+ `Skipped self-referential parent propagation of ${data.id} to ${parentHexagon} (hologram soul already points there).`
25160
+ );
25161
+ return true;
25162
+ }
25151
25163
  await holosphere.put(parentHexagon, lens, payloadToPut, null, {
25152
25164
  disableHologramRedirection: true,
25153
25165
  autoPropagate: false