holosphere 1.3.0-alpha3 → 1.3.0-alpha4

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.
@@ -1,5 +1,5 @@
1
1
  /**
2
- * HoloSphere Bundle v1.3.0-alpha3
2
+ * HoloSphere Bundle v1.3.0-alpha4
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-alpha3/holosphere-bundle.js"></script>
12
+ * <script src="https://unpkg.com/holosphere@1.3.0-alpha4/holosphere-bundle.js"></script>
13
13
  * <script>
14
14
  * const hs = new HoloSphere('myapp');
15
15
  * </script>
@@ -24348,6 +24348,23 @@ var HoloSphere = (() => {
24348
24348
  }
24349
24349
 
24350
24350
  // federation.js
24351
+ async function getHolonName(holosphere, space) {
24352
+ if (!holosphere || !space) return null;
24353
+ try {
24354
+ const settings = await holosphere.get(space, "settings", space);
24355
+ if (!settings) return null;
24356
+ if (Array.isArray(settings)) {
24357
+ const found = settings.find((s) => s && typeof s.name === "string" && s.name.trim() !== "");
24358
+ return found ? found.name : null;
24359
+ }
24360
+ if (typeof settings.name === "string" && settings.name.trim() !== "") {
24361
+ return settings.name;
24362
+ }
24363
+ return null;
24364
+ } catch {
24365
+ return null;
24366
+ }
24367
+ }
24351
24368
  async function federate(holosphere, spaceId1, spaceId2, password1 = null, password2 = null, bidirectional = true, lensConfig = {}) {
24352
24369
  if (!spaceId1 || !spaceId2) {
24353
24370
  throw new Error("federate: Missing required space IDs");
@@ -24450,7 +24467,14 @@ var HoloSphere = (() => {
24450
24467
  }
24451
24468
  const subscriptions2 = [];
24452
24469
  let lastNotificationTime = {};
24470
+ const partnerNames = /* @__PURE__ */ new Map();
24453
24471
  if (fedInfo.inbound && fedInfo.inbound.length > 0) {
24472
+ await Promise.all(
24473
+ fedInfo.inbound.map(async (space) => {
24474
+ const name = await getHolonName(holosphere, space);
24475
+ partnerNames.set(space, name);
24476
+ })
24477
+ );
24454
24478
  for (const federatedSpace of fedInfo.inbound) {
24455
24479
  for (const lens of lenses) {
24456
24480
  try {
@@ -24465,10 +24489,13 @@ var HoloSphere = (() => {
24465
24489
  }
24466
24490
  lastNotificationTime[key] = now;
24467
24491
  }
24468
- if (!data.federation) {
24469
- data.federation = {
24492
+ if (!data._federation) {
24493
+ const partnerName = partnerNames.get(federatedSpace);
24494
+ data._federation = {
24470
24495
  origin: federatedSpace,
24471
- timestamp: now
24496
+ sourceLens: lens,
24497
+ timestamp: now,
24498
+ ...partnerName ? { originName: partnerName } : {}
24472
24499
  };
24473
24500
  }
24474
24501
  await callback(data, federatedSpace, lens);
@@ -24661,6 +24688,25 @@ var HoloSphere = (() => {
24661
24688
  const federatedSpaces = maxFederatedSpaces === -1 ? fedInfo.inbound : fedInfo.inbound.slice(0, maxFederatedSpaces);
24662
24689
  spacesToQuery = spacesToQuery.concat(federatedSpaces);
24663
24690
  }
24691
+ const remoteSpaces = spacesToQuery.filter((s) => s !== holon);
24692
+ const spaceNames = /* @__PURE__ */ new Map();
24693
+ await Promise.all(
24694
+ remoteSpaces.map(async (space) => {
24695
+ const name = await getHolonName(holosphere, space);
24696
+ spaceNames.set(space, name);
24697
+ })
24698
+ );
24699
+ const tagWithSource = (item, space) => {
24700
+ if (!item || space === holon) return item;
24701
+ const originName = spaceNames.get(space);
24702
+ const fed = {
24703
+ ...item._federation || {},
24704
+ origin: space,
24705
+ sourceLens: lens
24706
+ };
24707
+ if (originName) fed.originName = originName;
24708
+ return { ...item, _federation: fed };
24709
+ };
24664
24710
  for (const currentSpace of spacesToQuery) {
24665
24711
  if (queryIds && Array.isArray(queryIds)) {
24666
24712
  console.log(`Fetching specific IDs from ${currentSpace}: ${queryIds.join(", ")}`);
@@ -24669,7 +24715,7 @@ var HoloSphere = (() => {
24669
24715
  fetchPromises.push(
24670
24716
  holosphere.get(currentSpace, lens, itemId).then((item) => {
24671
24717
  if (item) {
24672
- fetchedItems.set(itemId, item);
24718
+ fetchedItems.set(itemId, tagWithSource(item, currentSpace));
24673
24719
  }
24674
24720
  }).catch((err) => console.warn(`Error fetching item ${itemId} from ${currentSpace}: ${err.message}`))
24675
24721
  );
@@ -24683,7 +24729,7 @@ var HoloSphere = (() => {
24683
24729
  holosphere.getAll(currentSpace, lens).then((items) => {
24684
24730
  for (const item of items) {
24685
24731
  if (item && item[idField] && !fetchedItems.has(item[idField])) {
24686
- fetchedItems.set(item[idField], item);
24732
+ fetchedItems.set(item[idField], tagWithSource(item, currentSpace));
24687
24733
  }
24688
24734
  }
24689
24735
  }).catch((err) => console.warn(`Error fetching all items from ${currentSpace}: ${err.message}`))
@@ -24715,7 +24761,21 @@ var HoloSphere = (() => {
24715
24761
  );
24716
24762
  console.log(`Original data found via soul path:`, JSON.stringify(originalData));
24717
24763
  if (originalData) {
24718
- result[i] = attachHologramMeta(originalData, item.soul);
24764
+ const withMeta = attachHologramMeta(originalData, item.soul);
24765
+ if (withMeta._hologram?.sourceHolon) {
24766
+ let sourceHolonName = spaceNames.get(withMeta._hologram.sourceHolon);
24767
+ if (sourceHolonName === void 0) {
24768
+ sourceHolonName = await getHolonName(holosphere, withMeta._hologram.sourceHolon);
24769
+ spaceNames.set(withMeta._hologram.sourceHolon, sourceHolonName);
24770
+ }
24771
+ if (sourceHolonName) {
24772
+ withMeta._hologram = {
24773
+ ...withMeta._hologram,
24774
+ sourceHolonName
24775
+ };
24776
+ }
24777
+ }
24778
+ result[i] = withMeta;
24719
24779
  } else {
24720
24780
  result[i] = {
24721
24781
  id: item.id,
@@ -24839,6 +24899,7 @@ var HoloSphere = (() => {
24839
24899
  });
24840
24900
  if (spaces.length > 0) {
24841
24901
  const isAlreadyHologram = holosphere.isHologram(data);
24902
+ const ownName = await getHolonName(holosphere, holon);
24842
24903
  const propagatePromises = spaces.map(async (targetSpace) => {
24843
24904
  try {
24844
24905
  let payloadToPut;
@@ -24848,7 +24909,8 @@ var HoloSphere = (() => {
24848
24909
  sourceLens: lens,
24849
24910
  // The lens from which this data is being propagated
24850
24911
  propagatedAt: Date.now(),
24851
- originalId: data.id
24912
+ originalId: data.id,
24913
+ ...ownName ? { originName: ownName } : {}
24852
24914
  };
24853
24915
  if (useHolograms && !isAlreadyHologram) {
24854
24916
  const newHologram = holosphere.createHologram(holon, lens, data);
@@ -24933,6 +24995,7 @@ var HoloSphere = (() => {
24933
24995
  if (parentHexagons.length > 0) {
24934
24996
  result.parentPropagation.messages.push(`Found ${parentHexagons.length} parent hexagons to propagate to: ${parentHexagons.join(", ")}`);
24935
24997
  const isAlreadyHologram = holosphere.isHologram(data);
24998
+ const ownNameParent = await getHolonName(holosphere, holon);
24936
24999
  const parentPropagatePromises = parentHexagons.map(async (parentHexagon) => {
24937
25000
  try {
24938
25001
  let payloadToPut;
@@ -24945,8 +25008,9 @@ var HoloSphere = (() => {
24945
25008
  originalId: data.id,
24946
25009
  propagationType: "parent",
24947
25010
  // Indicate this is parent propagation
24948
- parentLevel: holonResolution - getResolution(parentHexagon)
25011
+ parentLevel: holonResolution - getResolution(parentHexagon),
24949
25012
  // How many levels up
25013
+ ...ownNameParent ? { originName: ownNameParent } : {}
24950
25014
  };
24951
25015
  if (useHolograms && !isAlreadyHologram) {
24952
25016
  const newHologram = holosphere.createHologram(holon, lens, data);
@@ -25214,6 +25278,45 @@ var HoloSphere = (() => {
25214
25278
  }
25215
25279
 
25216
25280
  // content.js
25281
+ function sanitizeForStorage(value, path = "", seen = /* @__PURE__ */ new WeakSet(), warnings = []) {
25282
+ if (value === null) return null;
25283
+ const t = typeof value;
25284
+ if (t === "number") {
25285
+ if (!Number.isFinite(value)) {
25286
+ warnings.push(`${path || "<root>"}: ${value} (non-finite number)`);
25287
+ return void 0;
25288
+ }
25289
+ return value;
25290
+ }
25291
+ if (t === "string" || t === "boolean") return value;
25292
+ if (t === "undefined" || t === "function" || t === "symbol" || t === "bigint") {
25293
+ warnings.push(`${path || "<root>"}: ${t}`);
25294
+ return void 0;
25295
+ }
25296
+ if (t === "object") {
25297
+ if (seen.has(value)) {
25298
+ warnings.push(`${path || "<root>"}: circular reference`);
25299
+ return void 0;
25300
+ }
25301
+ seen.add(value);
25302
+ if (Array.isArray(value)) {
25303
+ const out2 = [];
25304
+ for (let i = 0; i < value.length; i++) {
25305
+ const cleaned = sanitizeForStorage(value[i], `${path}[${i}]`, seen, warnings);
25306
+ out2.push(cleaned === void 0 ? null : cleaned);
25307
+ }
25308
+ return out2;
25309
+ }
25310
+ const out = {};
25311
+ for (const k of Object.keys(value)) {
25312
+ const cleaned = sanitizeForStorage(value[k], path ? `${path}.${k}` : k, seen, warnings);
25313
+ if (cleaned !== void 0) out[k] = cleaned;
25314
+ }
25315
+ return out;
25316
+ }
25317
+ warnings.push(`${path || "<root>"}: unsupported type ${t}`);
25318
+ return void 0;
25319
+ }
25217
25320
  async function put(holoInstance, holon, lens, data, password = null, options = {}) {
25218
25321
  if (!data) {
25219
25322
  throw new Error("put: Missing required data parameter");
@@ -25311,13 +25414,16 @@ var HoloSphere = (() => {
25311
25414
  }
25312
25415
  return new Promise((resolve, reject) => {
25313
25416
  try {
25314
- let dataToStore = { ...data };
25315
- if (dataToStore._meta !== void 0) {
25316
- delete dataToStore._meta;
25317
- }
25318
- if (dataToStore._hologram !== void 0) {
25319
- delete dataToStore._hologram;
25417
+ const sanitizeWarnings = [];
25418
+ let dataToStore = sanitizeForStorage(data, "", /* @__PURE__ */ new WeakSet(), sanitizeWarnings) || {};
25419
+ if (sanitizeWarnings.length > 0) {
25420
+ console.warn(
25421
+ `holosphere.put: sanitized ${sanitizeWarnings.length} field(s) at ${targetHolon}/${targetLens}/${targetKey} (id=${data.id}):`,
25422
+ sanitizeWarnings
25423
+ );
25320
25424
  }
25425
+ if (dataToStore._meta !== void 0) delete dataToStore._meta;
25426
+ if (dataToStore._hologram !== void 0) delete dataToStore._hologram;
25321
25427
  const payload = JSON.stringify(dataToStore);
25322
25428
  const putCallback = async (ack) => {
25323
25429
  if (ack.err) {