holosphere 1.3.0-alpha0 → 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.
- package/content.js +147 -65
- package/federation.js +319 -319
- package/global.js +58 -47
- package/hologram.js +38 -14
- package/holosphere-bundle.esm.js +525 -441
- package/holosphere-bundle.js +525 -441
- package/holosphere-bundle.min.js +8 -8
- package/holosphere.d.ts +50 -8
- package/holosphere.js +24 -19
- package/package.json +1 -1
package/holosphere-bundle.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* HoloSphere Bundle v1.3.0-
|
|
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-
|
|
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>
|
|
@@ -7067,7 +7067,7 @@ var HoloSphere = (() => {
|
|
|
7067
7067
|
constructor(opts = {}) {
|
|
7068
7068
|
this.schemas = {};
|
|
7069
7069
|
this.refs = {};
|
|
7070
|
-
this.formats =
|
|
7070
|
+
this.formats = /* @__PURE__ */ Object.create(null);
|
|
7071
7071
|
this._compilations = /* @__PURE__ */ new Set();
|
|
7072
7072
|
this._loading = {};
|
|
7073
7073
|
this._cache = /* @__PURE__ */ new Map();
|
|
@@ -7848,6 +7848,7 @@ var HoloSphere = (() => {
|
|
|
7848
7848
|
"use strict";
|
|
7849
7849
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7850
7850
|
var code_1 = require_code2();
|
|
7851
|
+
var util_1 = require_util();
|
|
7851
7852
|
var codegen_1 = require_codegen();
|
|
7852
7853
|
var error = {
|
|
7853
7854
|
message: ({ schemaCode }) => (0, codegen_1.str)`must match pattern "${schemaCode}"`,
|
|
@@ -7860,10 +7861,18 @@ var HoloSphere = (() => {
|
|
|
7860
7861
|
$data: true,
|
|
7861
7862
|
error,
|
|
7862
7863
|
code(cxt) {
|
|
7863
|
-
const { data, $data, schema, schemaCode, it } = cxt;
|
|
7864
|
+
const { gen, data, $data, schema, schemaCode, it } = cxt;
|
|
7864
7865
|
const u = it.opts.unicodeRegExp ? "u" : "";
|
|
7865
|
-
|
|
7866
|
-
|
|
7866
|
+
if ($data) {
|
|
7867
|
+
const { regExp } = it.opts.code;
|
|
7868
|
+
const regExpCode = regExp.code === "new RegExp" ? (0, codegen_1._)`new RegExp` : (0, util_1.useFunc)(gen, regExp);
|
|
7869
|
+
const valid = gen.let("valid");
|
|
7870
|
+
gen.try(() => gen.assign(valid, (0, codegen_1._)`${regExpCode}(${schemaCode}, ${u}).test(${data})`), () => gen.assign(valid, false));
|
|
7871
|
+
cxt.fail$data((0, codegen_1._)`!${valid}`);
|
|
7872
|
+
} else {
|
|
7873
|
+
const regExp = (0, code_1.usePattern)(cxt, schema);
|
|
7874
|
+
cxt.fail$data((0, codegen_1._)`!${regExp}.test(${data})`);
|
|
7875
|
+
}
|
|
7867
7876
|
}
|
|
7868
7877
|
};
|
|
7869
7878
|
exports.default = def;
|
|
@@ -10074,7 +10083,7 @@ var HoloSphere = (() => {
|
|
|
10074
10083
|
var discriminator_1 = require_discriminator();
|
|
10075
10084
|
var json_schema_2019_09_1 = require_json_schema_2019_09();
|
|
10076
10085
|
var META_SCHEMA_ID = "https://json-schema.org/draft/2019-09/schema";
|
|
10077
|
-
var
|
|
10086
|
+
var Ajv20192 = class extends core_1.default {
|
|
10078
10087
|
constructor(opts = {}) {
|
|
10079
10088
|
super({
|
|
10080
10089
|
...opts,
|
|
@@ -10104,11 +10113,11 @@ var HoloSphere = (() => {
|
|
|
10104
10113
|
return this.opts.defaultMeta = super.defaultMeta() || (this.getSchema(META_SCHEMA_ID) ? META_SCHEMA_ID : void 0);
|
|
10105
10114
|
}
|
|
10106
10115
|
};
|
|
10107
|
-
exports.Ajv2019 =
|
|
10108
|
-
module.exports = exports =
|
|
10109
|
-
module.exports.Ajv2019 =
|
|
10116
|
+
exports.Ajv2019 = Ajv20192;
|
|
10117
|
+
module.exports = exports = Ajv20192;
|
|
10118
|
+
module.exports.Ajv2019 = Ajv20192;
|
|
10110
10119
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10111
|
-
exports.default =
|
|
10120
|
+
exports.default = Ajv20192;
|
|
10112
10121
|
var validate_1 = require_validate();
|
|
10113
10122
|
Object.defineProperty(exports, "KeywordCxt", { enumerable: true, get: function() {
|
|
10114
10123
|
return validate_1.KeywordCxt;
|
|
@@ -24223,9 +24232,139 @@ var HoloSphere = (() => {
|
|
|
24223
24232
|
|
|
24224
24233
|
// holosphere.js
|
|
24225
24234
|
var import_gun = __toESM(require_browser(), 1);
|
|
24226
|
-
var
|
|
24235
|
+
var import__ = __toESM(require__(), 1);
|
|
24236
|
+
|
|
24237
|
+
// hologram.js
|
|
24238
|
+
function createHologram(holoInstance, holon, lens, data) {
|
|
24239
|
+
if (isHologram(data)) {
|
|
24240
|
+
return {
|
|
24241
|
+
id: data.id,
|
|
24242
|
+
soul: data.soul
|
|
24243
|
+
};
|
|
24244
|
+
}
|
|
24245
|
+
if (!holon || !lens || !data || !data.id) {
|
|
24246
|
+
throw new Error("createHologram: Missing required parameters for non-hologram data");
|
|
24247
|
+
}
|
|
24248
|
+
const soul = `${holoInstance.appname}/${holon}/${lens}/${data.id}`;
|
|
24249
|
+
return {
|
|
24250
|
+
id: data.id,
|
|
24251
|
+
soul
|
|
24252
|
+
};
|
|
24253
|
+
}
|
|
24254
|
+
function parseSoulPath(soul) {
|
|
24255
|
+
if (typeof soul !== "string") return null;
|
|
24256
|
+
const parts = soul.split("/");
|
|
24257
|
+
if (parts.length < 4) return null;
|
|
24258
|
+
const key = parts.slice(3).join("/");
|
|
24259
|
+
return {
|
|
24260
|
+
appname: parts[0],
|
|
24261
|
+
holon: parts[1],
|
|
24262
|
+
lens: parts[2],
|
|
24263
|
+
key
|
|
24264
|
+
};
|
|
24265
|
+
}
|
|
24266
|
+
function isHologram(data) {
|
|
24267
|
+
if (!data || typeof data !== "object") {
|
|
24268
|
+
return false;
|
|
24269
|
+
}
|
|
24270
|
+
if (data.id && typeof data.soul === "string" && data.soul.length > 0) {
|
|
24271
|
+
if (data.soul.includes("/")) {
|
|
24272
|
+
return true;
|
|
24273
|
+
}
|
|
24274
|
+
}
|
|
24275
|
+
return false;
|
|
24276
|
+
}
|
|
24277
|
+
function attachHologramMeta(originalData, hologramSoul) {
|
|
24278
|
+
const parts = parseSoulPath(hologramSoul);
|
|
24279
|
+
return {
|
|
24280
|
+
...originalData,
|
|
24281
|
+
_hologram: {
|
|
24282
|
+
isHologram: true,
|
|
24283
|
+
soul: hologramSoul,
|
|
24284
|
+
sourceHolon: parts?.holon ?? null,
|
|
24285
|
+
sourceLens: parts?.lens ?? null,
|
|
24286
|
+
sourceKey: parts?.key ?? null,
|
|
24287
|
+
resolvedAt: Date.now()
|
|
24288
|
+
}
|
|
24289
|
+
};
|
|
24290
|
+
}
|
|
24291
|
+
async function resolveHologram(holoInstance, hologram, options = {}) {
|
|
24292
|
+
if (!isHologram(hologram)) {
|
|
24293
|
+
return hologram;
|
|
24294
|
+
}
|
|
24295
|
+
const {
|
|
24296
|
+
followHolograms = true,
|
|
24297
|
+
visited = /* @__PURE__ */ new Set(),
|
|
24298
|
+
maxDepth = 10,
|
|
24299
|
+
currentDepth = 0
|
|
24300
|
+
} = options;
|
|
24301
|
+
if (currentDepth >= maxDepth) {
|
|
24302
|
+
console.warn(`!!! Maximum resolution depth (${maxDepth}) reached for soul: ${hologram.soul}. Stopping resolution.`);
|
|
24303
|
+
return null;
|
|
24304
|
+
}
|
|
24305
|
+
if (hologram.soul && visited.has(hologram.soul)) {
|
|
24306
|
+
console.warn(`!!! CIRCULAR hologram detected for soul: ${hologram.soul}. Breaking loop.`);
|
|
24307
|
+
return null;
|
|
24308
|
+
}
|
|
24309
|
+
try {
|
|
24310
|
+
if (hologram.soul) {
|
|
24311
|
+
const soulInfo = parseSoulPath(hologram.soul);
|
|
24312
|
+
if (!soulInfo) {
|
|
24313
|
+
console.warn(`Invalid soul format: ${hologram.soul}`);
|
|
24314
|
+
return null;
|
|
24315
|
+
}
|
|
24316
|
+
const nextVisited = new Set(visited);
|
|
24317
|
+
nextVisited.add(hologram.soul);
|
|
24318
|
+
const originalData = await holoInstance.get(
|
|
24319
|
+
soulInfo.holon,
|
|
24320
|
+
soulInfo.lens,
|
|
24321
|
+
soulInfo.key,
|
|
24322
|
+
null,
|
|
24323
|
+
{
|
|
24324
|
+
resolveHolograms: followHolograms,
|
|
24325
|
+
visited: nextVisited,
|
|
24326
|
+
maxDepth,
|
|
24327
|
+
currentDepth: currentDepth + 1
|
|
24328
|
+
}
|
|
24329
|
+
);
|
|
24330
|
+
if (originalData && !originalData._invalidHologram) {
|
|
24331
|
+
return attachHologramMeta(originalData, hologram.soul);
|
|
24332
|
+
} else {
|
|
24333
|
+
console.warn(`!!! Original data NOT FOUND for soul: ${hologram.soul}. Removing broken hologram.`);
|
|
24334
|
+
return null;
|
|
24335
|
+
}
|
|
24336
|
+
} else {
|
|
24337
|
+
console.warn("!!! resolveHologram called with object missing soul:", hologram);
|
|
24338
|
+
return null;
|
|
24339
|
+
}
|
|
24340
|
+
} catch (error) {
|
|
24341
|
+
if (error.message?.startsWith("CIRCULAR_REFERENCE")) {
|
|
24342
|
+
console.warn(`!!! Circular reference detected during hologram resolution: ${error.message}`);
|
|
24343
|
+
return null;
|
|
24344
|
+
}
|
|
24345
|
+
console.error(`!!! Error resolving hologram: ${error.message}`, error);
|
|
24346
|
+
return null;
|
|
24347
|
+
}
|
|
24348
|
+
}
|
|
24227
24349
|
|
|
24228
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
|
+
}
|
|
24229
24368
|
async function federate(holosphere, spaceId1, spaceId2, password1 = null, password2 = null, bidirectional = true, lensConfig = {}) {
|
|
24230
24369
|
if (!spaceId1 || !spaceId2) {
|
|
24231
24370
|
throw new Error("federate: Missing required space IDs");
|
|
@@ -24233,110 +24372,85 @@ var HoloSphere = (() => {
|
|
|
24233
24372
|
if (spaceId1 === spaceId2) {
|
|
24234
24373
|
throw new Error("Cannot federate a space with itself");
|
|
24235
24374
|
}
|
|
24236
|
-
const {
|
|
24237
|
-
if (!Array.isArray(
|
|
24238
|
-
throw new Error("federate: lensConfig.
|
|
24239
|
-
}
|
|
24240
|
-
const
|
|
24241
|
-
|
|
24375
|
+
const { inbound = [], outbound = [] } = lensConfig;
|
|
24376
|
+
if (!Array.isArray(inbound) || !Array.isArray(outbound)) {
|
|
24377
|
+
throw new Error("federate: lensConfig.inbound and lensConfig.outbound must be arrays");
|
|
24378
|
+
}
|
|
24379
|
+
const applyDirection = (fedInfo, partnerId, partnerInbound, partnerOutbound) => {
|
|
24380
|
+
if (!fedInfo.federated) fedInfo.federated = [];
|
|
24381
|
+
if (!fedInfo.inbound) fedInfo.inbound = [];
|
|
24382
|
+
if (!fedInfo.outbound) fedInfo.outbound = [];
|
|
24383
|
+
if (!fedInfo.lensConfig) fedInfo.lensConfig = {};
|
|
24384
|
+
if (!fedInfo.federated.includes(partnerId)) {
|
|
24385
|
+
fedInfo.federated.push(partnerId);
|
|
24386
|
+
}
|
|
24387
|
+
const hasInbound = partnerInbound.length > 0;
|
|
24388
|
+
const hasOutbound = partnerOutbound.length > 0;
|
|
24389
|
+
if (hasInbound && !fedInfo.inbound.includes(partnerId)) {
|
|
24390
|
+
fedInfo.inbound.push(partnerId);
|
|
24391
|
+
} else if (!hasInbound) {
|
|
24392
|
+
fedInfo.inbound = fedInfo.inbound.filter((id) => id !== partnerId);
|
|
24393
|
+
}
|
|
24394
|
+
if (hasOutbound && !fedInfo.outbound.includes(partnerId)) {
|
|
24395
|
+
fedInfo.outbound.push(partnerId);
|
|
24396
|
+
} else if (!hasOutbound) {
|
|
24397
|
+
fedInfo.outbound = fedInfo.outbound.filter((id) => id !== partnerId);
|
|
24398
|
+
}
|
|
24399
|
+
fedInfo.lensConfig[partnerId] = {
|
|
24400
|
+
inbound: [...partnerInbound],
|
|
24401
|
+
outbound: [...partnerOutbound],
|
|
24402
|
+
timestamp: Date.now()
|
|
24403
|
+
};
|
|
24404
|
+
fedInfo.timestamp = Date.now();
|
|
24405
|
+
};
|
|
24242
24406
|
try {
|
|
24243
24407
|
let fedInfo1 = null;
|
|
24244
24408
|
try {
|
|
24245
24409
|
fedInfo1 = await holosphere.getGlobal("federation", spaceId1, password1);
|
|
24246
|
-
} catch
|
|
24410
|
+
} catch {
|
|
24247
24411
|
}
|
|
24248
24412
|
if (fedInfo1 == null) {
|
|
24249
24413
|
fedInfo1 = {
|
|
24250
24414
|
id: spaceId1,
|
|
24251
24415
|
name: spaceId1,
|
|
24252
|
-
|
|
24253
|
-
|
|
24416
|
+
federated: [],
|
|
24417
|
+
inbound: [],
|
|
24418
|
+
outbound: [],
|
|
24254
24419
|
lensConfig: {},
|
|
24255
|
-
|
|
24420
|
+
partnerNames: {},
|
|
24256
24421
|
timestamp: Date.now()
|
|
24257
24422
|
};
|
|
24258
24423
|
}
|
|
24259
|
-
|
|
24260
|
-
if (!fedInfo1.notify) fedInfo1.notify = [];
|
|
24261
|
-
if (!fedInfo1.lensConfig) fedInfo1.lensConfig = {};
|
|
24262
|
-
if (!fedInfo1.federation.includes(spaceId2)) {
|
|
24263
|
-
fedInfo1.federation.push(spaceId2);
|
|
24264
|
-
}
|
|
24265
|
-
if (!fedInfo1.notify.includes(spaceId2)) {
|
|
24266
|
-
fedInfo1.notify.push(spaceId2);
|
|
24267
|
-
}
|
|
24268
|
-
const newLensConfigsForSpace1 = { ...fedInfo1.lensConfig || {} };
|
|
24269
|
-
newLensConfigsForSpace1[spaceId2] = {
|
|
24270
|
-
// Add/update config for the target spaceId2
|
|
24271
|
-
federate: [...federateLenses],
|
|
24272
|
-
// federateLenses & notifyLenses are from the main lensConfig parameter
|
|
24273
|
-
notify: [...notifyLenses],
|
|
24274
|
-
timestamp: Date.now()
|
|
24275
|
-
};
|
|
24276
|
-
fedInfo1.lensConfig = newLensConfigsForSpace1;
|
|
24277
|
-
fedInfo1.timestamp = Date.now();
|
|
24424
|
+
applyDirection(fedInfo1, spaceId2, inbound, outbound);
|
|
24278
24425
|
try {
|
|
24279
24426
|
await holosphere.putGlobal("federation", fedInfo1, password1);
|
|
24280
24427
|
} catch (error) {
|
|
24281
24428
|
throw new Error(`Failed to create federation: ${error.message}`);
|
|
24282
24429
|
}
|
|
24283
|
-
{
|
|
24430
|
+
if (bidirectional) {
|
|
24284
24431
|
let fedInfo2 = null;
|
|
24285
24432
|
try {
|
|
24286
24433
|
fedInfo2 = await holosphere.getGlobal("federation", spaceId2, password2);
|
|
24287
|
-
} catch
|
|
24434
|
+
} catch {
|
|
24288
24435
|
}
|
|
24289
24436
|
if (fedInfo2 == null) {
|
|
24290
24437
|
fedInfo2 = {
|
|
24291
24438
|
id: spaceId2,
|
|
24292
24439
|
name: spaceId2,
|
|
24293
|
-
|
|
24294
|
-
|
|
24440
|
+
federated: [],
|
|
24441
|
+
inbound: [],
|
|
24442
|
+
outbound: [],
|
|
24295
24443
|
lensConfig: {},
|
|
24296
|
-
|
|
24444
|
+
partnerNames: {},
|
|
24297
24445
|
timestamp: Date.now()
|
|
24298
24446
|
};
|
|
24299
24447
|
}
|
|
24300
|
-
|
|
24301
|
-
if (!fedInfo2.notify) fedInfo2.notify = [];
|
|
24302
|
-
if (!fedInfo2.lensConfig) fedInfo2.lensConfig = {};
|
|
24303
|
-
if (bidirectional && !fedInfo2.federation.includes(spaceId1)) {
|
|
24304
|
-
fedInfo2.federation.push(spaceId1);
|
|
24305
|
-
}
|
|
24306
|
-
if (!fedInfo2.notify.includes(spaceId1)) {
|
|
24307
|
-
fedInfo2.notify.push(spaceId1);
|
|
24308
|
-
}
|
|
24309
|
-
fedInfo2.lensConfig[spaceId1] = {
|
|
24310
|
-
federate: bidirectional ? [...federateLenses] : [],
|
|
24311
|
-
// Create a copy of the array
|
|
24312
|
-
notify: bidirectional ? [...notifyLenses] : [],
|
|
24313
|
-
// Create a copy of the array
|
|
24314
|
-
timestamp: Date.now()
|
|
24315
|
-
};
|
|
24316
|
-
fedInfo2.timestamp = Date.now();
|
|
24448
|
+
applyDirection(fedInfo2, spaceId1, outbound, inbound);
|
|
24317
24449
|
try {
|
|
24318
24450
|
await holosphere.putGlobal("federation", fedInfo2, password2);
|
|
24319
|
-
} catch
|
|
24451
|
+
} catch {
|
|
24320
24452
|
}
|
|
24321
24453
|
}
|
|
24322
|
-
const federationMeta = {
|
|
24323
|
-
id: `${spaceId1}_${spaceId2}`,
|
|
24324
|
-
space1: spaceId1,
|
|
24325
|
-
space2: spaceId2,
|
|
24326
|
-
created: Date.now(),
|
|
24327
|
-
status: "active",
|
|
24328
|
-
bidirectional,
|
|
24329
|
-
lensConfig: {
|
|
24330
|
-
federate: [...federateLenses],
|
|
24331
|
-
// Create a copy of the array
|
|
24332
|
-
notify: [...notifyLenses]
|
|
24333
|
-
// Create a copy of the array
|
|
24334
|
-
}
|
|
24335
|
-
};
|
|
24336
|
-
try {
|
|
24337
|
-
await holosphere.putGlobal("federationMeta", federationMeta);
|
|
24338
|
-
} catch (error) {
|
|
24339
|
-
}
|
|
24340
24454
|
return true;
|
|
24341
24455
|
} catch (error) {
|
|
24342
24456
|
throw error;
|
|
@@ -24353,8 +24467,15 @@ var HoloSphere = (() => {
|
|
|
24353
24467
|
}
|
|
24354
24468
|
const subscriptions2 = [];
|
|
24355
24469
|
let lastNotificationTime = {};
|
|
24356
|
-
|
|
24357
|
-
|
|
24470
|
+
const partnerNames = /* @__PURE__ */ new Map();
|
|
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
|
+
);
|
|
24478
|
+
for (const federatedSpace of fedInfo.inbound) {
|
|
24358
24479
|
for (const lens of lenses) {
|
|
24359
24480
|
try {
|
|
24360
24481
|
const sub = await holosphere.subscribe(federatedSpace, lens, async (data) => {
|
|
@@ -24368,10 +24489,13 @@ var HoloSphere = (() => {
|
|
|
24368
24489
|
}
|
|
24369
24490
|
lastNotificationTime[key] = now;
|
|
24370
24491
|
}
|
|
24371
|
-
if (!data.
|
|
24372
|
-
|
|
24492
|
+
if (!data._federation) {
|
|
24493
|
+
const partnerName = partnerNames.get(federatedSpace);
|
|
24494
|
+
data._federation = {
|
|
24373
24495
|
origin: federatedSpace,
|
|
24374
|
-
|
|
24496
|
+
sourceLens: lens,
|
|
24497
|
+
timestamp: now,
|
|
24498
|
+
...partnerName ? { originName: partnerName } : {}
|
|
24375
24499
|
};
|
|
24376
24500
|
}
|
|
24377
24501
|
await callback(data, federatedSpace, lens);
|
|
@@ -24416,8 +24540,8 @@ var HoloSphere = (() => {
|
|
|
24416
24540
|
const fedInfo = await getFederation(holosphere, spaceId, password);
|
|
24417
24541
|
if (fedInfo && fedInfo.lensConfig && fedInfo.lensConfig[targetSpaceId]) {
|
|
24418
24542
|
return {
|
|
24419
|
-
|
|
24420
|
-
|
|
24543
|
+
inbound: fedInfo.lensConfig[targetSpaceId].inbound || [],
|
|
24544
|
+
outbound: fedInfo.lensConfig[targetSpaceId].outbound || []
|
|
24421
24545
|
};
|
|
24422
24546
|
}
|
|
24423
24547
|
return null;
|
|
@@ -24440,14 +24564,20 @@ var HoloSphere = (() => {
|
|
|
24440
24564
|
if (!fedInfo1) {
|
|
24441
24565
|
console.warn(`No federation info found for ${spaceId1}. Skipping its update.`);
|
|
24442
24566
|
} else {
|
|
24443
|
-
if (!fedInfo1.
|
|
24444
|
-
if (!fedInfo1.
|
|
24445
|
-
|
|
24446
|
-
|
|
24447
|
-
fedInfo1.
|
|
24448
|
-
|
|
24567
|
+
if (!fedInfo1.federated) fedInfo1.federated = [];
|
|
24568
|
+
if (!fedInfo1.inbound) fedInfo1.inbound = [];
|
|
24569
|
+
if (!fedInfo1.outbound) fedInfo1.outbound = [];
|
|
24570
|
+
if (!fedInfo1.lensConfig) fedInfo1.lensConfig = {};
|
|
24571
|
+
if (!fedInfo1.partnerNames) fedInfo1.partnerNames = {};
|
|
24572
|
+
const beforeIn = fedInfo1.inbound.length;
|
|
24573
|
+
const beforeOut = fedInfo1.outbound.length;
|
|
24574
|
+
fedInfo1.federated = fedInfo1.federated.filter((id) => id !== spaceId2);
|
|
24575
|
+
fedInfo1.inbound = fedInfo1.inbound.filter((id) => id !== spaceId2);
|
|
24576
|
+
fedInfo1.outbound = fedInfo1.outbound.filter((id) => id !== spaceId2);
|
|
24577
|
+
delete fedInfo1.lensConfig[spaceId2];
|
|
24578
|
+
delete fedInfo1.partnerNames[spaceId2];
|
|
24449
24579
|
fedInfo1.timestamp = Date.now();
|
|
24450
|
-
console.log(`Unfederate:
|
|
24580
|
+
console.log(`Unfederate: removed ${spaceId2} from ${spaceId1}: inbound ${beforeIn} -> ${fedInfo1.inbound.length}, outbound ${beforeOut} -> ${fedInfo1.outbound.length}`);
|
|
24451
24581
|
try {
|
|
24452
24582
|
await holosphere.putGlobal("federation", fedInfo1, password1);
|
|
24453
24583
|
} catch (error) {
|
|
@@ -24462,10 +24592,19 @@ var HoloSphere = (() => {
|
|
|
24462
24592
|
} catch (error) {
|
|
24463
24593
|
console.error(`Error getting fedInfo2 for ${spaceId2} during unfederate: ${error.message}`);
|
|
24464
24594
|
}
|
|
24465
|
-
if (!fedInfo2
|
|
24466
|
-
console.warn(`No
|
|
24595
|
+
if (!fedInfo2) {
|
|
24596
|
+
console.warn(`No federation info found for ${spaceId2}. Skipping its update.`);
|
|
24467
24597
|
} else {
|
|
24468
|
-
fedInfo2.
|
|
24598
|
+
if (!fedInfo2.federated) fedInfo2.federated = [];
|
|
24599
|
+
if (!fedInfo2.inbound) fedInfo2.inbound = [];
|
|
24600
|
+
if (!fedInfo2.outbound) fedInfo2.outbound = [];
|
|
24601
|
+
if (!fedInfo2.lensConfig) fedInfo2.lensConfig = {};
|
|
24602
|
+
if (!fedInfo2.partnerNames) fedInfo2.partnerNames = {};
|
|
24603
|
+
fedInfo2.federated = fedInfo2.federated.filter((id) => id !== spaceId1);
|
|
24604
|
+
fedInfo2.inbound = fedInfo2.inbound.filter((id) => id !== spaceId1);
|
|
24605
|
+
fedInfo2.outbound = fedInfo2.outbound.filter((id) => id !== spaceId1);
|
|
24606
|
+
delete fedInfo2.lensConfig[spaceId1];
|
|
24607
|
+
delete fedInfo2.partnerNames[spaceId1];
|
|
24469
24608
|
fedInfo2.timestamp = Date.now();
|
|
24470
24609
|
try {
|
|
24471
24610
|
await holosphere.putGlobal("federation", fedInfo2, password2);
|
|
@@ -24498,19 +24637,19 @@ var HoloSphere = (() => {
|
|
|
24498
24637
|
throw new Error("removeNotify: Missing required space IDs");
|
|
24499
24638
|
}
|
|
24500
24639
|
try {
|
|
24501
|
-
|
|
24640
|
+
const fedInfo = await holosphere.getGlobal("federation", spaceId1, password1);
|
|
24502
24641
|
if (!fedInfo) {
|
|
24503
24642
|
throw new Error(`No federation info found for ${spaceId1}`);
|
|
24504
24643
|
}
|
|
24505
|
-
if (!fedInfo.
|
|
24506
|
-
if (fedInfo.
|
|
24507
|
-
|
|
24508
|
-
|
|
24509
|
-
|
|
24510
|
-
return true;
|
|
24511
|
-
} else {
|
|
24512
|
-
return false;
|
|
24644
|
+
if (!fedInfo.outbound) fedInfo.outbound = [];
|
|
24645
|
+
if (!fedInfo.outbound.includes(spaceId2)) return false;
|
|
24646
|
+
fedInfo.outbound = fedInfo.outbound.filter((id) => id !== spaceId2);
|
|
24647
|
+
if (fedInfo.lensConfig?.[spaceId2]) {
|
|
24648
|
+
fedInfo.lensConfig[spaceId2].outbound = [];
|
|
24513
24649
|
}
|
|
24650
|
+
fedInfo.timestamp = Date.now();
|
|
24651
|
+
await holosphere.putGlobal("federation", fedInfo, password1);
|
|
24652
|
+
return true;
|
|
24514
24653
|
} catch (error) {
|
|
24515
24654
|
throw error;
|
|
24516
24655
|
}
|
|
@@ -24545,10 +24684,29 @@ var HoloSphere = (() => {
|
|
|
24545
24684
|
if (includeLocal) {
|
|
24546
24685
|
spacesToQuery.push(holon);
|
|
24547
24686
|
}
|
|
24548
|
-
if (includeFederated && fedInfo && fedInfo.
|
|
24549
|
-
const federatedSpaces = maxFederatedSpaces === -1 ? fedInfo.
|
|
24687
|
+
if (includeFederated && fedInfo && fedInfo.inbound && fedInfo.inbound.length > 0) {
|
|
24688
|
+
const federatedSpaces = maxFederatedSpaces === -1 ? fedInfo.inbound : fedInfo.inbound.slice(0, maxFederatedSpaces);
|
|
24550
24689
|
spacesToQuery = spacesToQuery.concat(federatedSpaces);
|
|
24551
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
|
+
};
|
|
24552
24710
|
for (const currentSpace of spacesToQuery) {
|
|
24553
24711
|
if (queryIds && Array.isArray(queryIds)) {
|
|
24554
24712
|
console.log(`Fetching specific IDs from ${currentSpace}: ${queryIds.join(", ")}`);
|
|
@@ -24557,7 +24715,7 @@ var HoloSphere = (() => {
|
|
|
24557
24715
|
fetchPromises.push(
|
|
24558
24716
|
holosphere.get(currentSpace, lens, itemId).then((item) => {
|
|
24559
24717
|
if (item) {
|
|
24560
|
-
fetchedItems.set(itemId, item);
|
|
24718
|
+
fetchedItems.set(itemId, tagWithSource(item, currentSpace));
|
|
24561
24719
|
}
|
|
24562
24720
|
}).catch((err) => console.warn(`Error fetching item ${itemId} from ${currentSpace}: ${err.message}`))
|
|
24563
24721
|
);
|
|
@@ -24571,7 +24729,7 @@ var HoloSphere = (() => {
|
|
|
24571
24729
|
holosphere.getAll(currentSpace, lens).then((items) => {
|
|
24572
24730
|
for (const item of items) {
|
|
24573
24731
|
if (item && item[idField] && !fetchedItems.has(item[idField])) {
|
|
24574
|
-
fetchedItems.set(item[idField], item);
|
|
24732
|
+
fetchedItems.set(item[idField], tagWithSource(item, currentSpace));
|
|
24575
24733
|
}
|
|
24576
24734
|
}
|
|
24577
24735
|
}).catch((err) => console.warn(`Error fetching all items from ${currentSpace}: ${err.message}`))
|
|
@@ -24603,24 +24761,29 @@ var HoloSphere = (() => {
|
|
|
24603
24761
|
);
|
|
24604
24762
|
console.log(`Original data found via soul path:`, JSON.stringify(originalData));
|
|
24605
24763
|
if (originalData) {
|
|
24606
|
-
|
|
24607
|
-
|
|
24608
|
-
|
|
24609
|
-
|
|
24610
|
-
|
|
24611
|
-
|
|
24612
|
-
timestamp: Date.now()
|
|
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);
|
|
24613
24770
|
}
|
|
24614
|
-
|
|
24771
|
+
if (sourceHolonName) {
|
|
24772
|
+
withMeta._hologram = {
|
|
24773
|
+
...withMeta._hologram,
|
|
24774
|
+
sourceHolonName
|
|
24775
|
+
};
|
|
24776
|
+
}
|
|
24777
|
+
}
|
|
24778
|
+
result[i] = withMeta;
|
|
24615
24779
|
} else {
|
|
24616
24780
|
result[i] = {
|
|
24617
24781
|
id: item.id,
|
|
24618
|
-
|
|
24619
|
-
|
|
24620
|
-
resolved: false,
|
|
24782
|
+
_hologram: {
|
|
24783
|
+
isHologram: false,
|
|
24621
24784
|
soul: item.soul,
|
|
24622
24785
|
error: "Referenced data not found",
|
|
24623
|
-
|
|
24786
|
+
resolvedAt: Date.now()
|
|
24624
24787
|
}
|
|
24625
24788
|
};
|
|
24626
24789
|
}
|
|
@@ -24628,55 +24791,25 @@ var HoloSphere = (() => {
|
|
|
24628
24791
|
console.warn(`Soul doesn't match expected format: ${item.soul}`);
|
|
24629
24792
|
result[i] = {
|
|
24630
24793
|
id: item.id,
|
|
24631
|
-
|
|
24632
|
-
|
|
24633
|
-
resolved: false,
|
|
24794
|
+
_hologram: {
|
|
24795
|
+
isHologram: false,
|
|
24634
24796
|
soul: item.soul,
|
|
24635
24797
|
error: "Invalid soul format",
|
|
24636
|
-
|
|
24798
|
+
resolvedAt: Date.now()
|
|
24637
24799
|
}
|
|
24638
24800
|
};
|
|
24639
24801
|
}
|
|
24640
24802
|
} catch (refError) {
|
|
24641
24803
|
result[i] = {
|
|
24642
24804
|
id: item.id,
|
|
24643
|
-
|
|
24644
|
-
|
|
24645
|
-
resolved: false,
|
|
24805
|
+
_hologram: {
|
|
24806
|
+
isHologram: false,
|
|
24646
24807
|
soul: item.soul,
|
|
24647
24808
|
error: refError.message || "Error resolving reference",
|
|
24648
|
-
|
|
24809
|
+
resolvedAt: Date.now()
|
|
24649
24810
|
}
|
|
24650
24811
|
};
|
|
24651
24812
|
}
|
|
24652
|
-
} else if (item._federation && item._federation.isReference) {
|
|
24653
|
-
console.log(`Found legacy reference: ${item._federation.origin}/${item._federation.lens}/${item[idField]}`);
|
|
24654
|
-
try {
|
|
24655
|
-
const reference = item._federation;
|
|
24656
|
-
console.log(`Getting original data from ${reference.origin} / ${reference.lens} / ${item[idField]}`);
|
|
24657
|
-
const originalData = await holosphere.get(
|
|
24658
|
-
reference.origin,
|
|
24659
|
-
reference.lens,
|
|
24660
|
-
item[idField],
|
|
24661
|
-
null,
|
|
24662
|
-
{ resolveReferences: false }
|
|
24663
|
-
// Prevent infinite recursion
|
|
24664
|
-
);
|
|
24665
|
-
console.log(`Original data found:`, JSON.stringify(originalData));
|
|
24666
|
-
if (originalData) {
|
|
24667
|
-
result[i] = {
|
|
24668
|
-
...originalData,
|
|
24669
|
-
_federation: {
|
|
24670
|
-
...reference,
|
|
24671
|
-
resolved: true,
|
|
24672
|
-
timestamp: Date.now()
|
|
24673
|
-
}
|
|
24674
|
-
};
|
|
24675
|
-
} else {
|
|
24676
|
-
console.warn(`Could not resolve legacy reference: original data not found`);
|
|
24677
|
-
}
|
|
24678
|
-
} catch (refError) {
|
|
24679
|
-
}
|
|
24680
24813
|
}
|
|
24681
24814
|
}
|
|
24682
24815
|
}
|
|
@@ -24743,8 +24876,8 @@ var HoloSphere = (() => {
|
|
|
24743
24876
|
};
|
|
24744
24877
|
try {
|
|
24745
24878
|
const fedInfo = await getFederation(holosphere, holon, password);
|
|
24746
|
-
if (fedInfo && fedInfo.
|
|
24747
|
-
let spaces = fedInfo.
|
|
24879
|
+
if (fedInfo && fedInfo.outbound && fedInfo.outbound.length > 0) {
|
|
24880
|
+
let spaces = fedInfo.outbound;
|
|
24748
24881
|
if (targetSpaces && Array.isArray(targetSpaces) && targetSpaces.length > 0) {
|
|
24749
24882
|
spaces = spaces.filter((space) => targetSpaces.includes(space));
|
|
24750
24883
|
}
|
|
@@ -24756,17 +24889,17 @@ var HoloSphere = (() => {
|
|
|
24756
24889
|
result.skipped++;
|
|
24757
24890
|
return false;
|
|
24758
24891
|
}
|
|
24759
|
-
const
|
|
24760
|
-
const
|
|
24761
|
-
const shouldPropagate = shouldFederate;
|
|
24892
|
+
const outboundLenses = Array.isArray(spaceConfig.outbound) ? spaceConfig.outbound : [];
|
|
24893
|
+
const shouldPropagate = outboundLenses.includes("*") || outboundLenses.includes(lens);
|
|
24762
24894
|
if (!shouldPropagate) {
|
|
24763
|
-
result.messages.push(`Propagation of lens '${lens}' to target space ${targetSpace} skipped: lens not in '
|
|
24895
|
+
result.messages.push(`Propagation of lens '${lens}' to target space ${targetSpace} skipped: lens not in 'outbound' configuration.`);
|
|
24764
24896
|
result.skipped++;
|
|
24765
24897
|
}
|
|
24766
24898
|
return shouldPropagate;
|
|
24767
24899
|
});
|
|
24768
24900
|
if (spaces.length > 0) {
|
|
24769
24901
|
const isAlreadyHologram = holosphere.isHologram(data);
|
|
24902
|
+
const ownName = await getHolonName(holosphere, holon);
|
|
24770
24903
|
const propagatePromises = spaces.map(async (targetSpace) => {
|
|
24771
24904
|
try {
|
|
24772
24905
|
let payloadToPut;
|
|
@@ -24776,7 +24909,8 @@ var HoloSphere = (() => {
|
|
|
24776
24909
|
sourceLens: lens,
|
|
24777
24910
|
// The lens from which this data is being propagated
|
|
24778
24911
|
propagatedAt: Date.now(),
|
|
24779
|
-
originalId: data.id
|
|
24912
|
+
originalId: data.id,
|
|
24913
|
+
...ownName ? { originName: ownName } : {}
|
|
24780
24914
|
};
|
|
24781
24915
|
if (useHolograms && !isAlreadyHologram) {
|
|
24782
24916
|
const newHologram = holosphere.createHologram(holon, lens, data);
|
|
@@ -24861,6 +24995,7 @@ var HoloSphere = (() => {
|
|
|
24861
24995
|
if (parentHexagons.length > 0) {
|
|
24862
24996
|
result.parentPropagation.messages.push(`Found ${parentHexagons.length} parent hexagons to propagate to: ${parentHexagons.join(", ")}`);
|
|
24863
24997
|
const isAlreadyHologram = holosphere.isHologram(data);
|
|
24998
|
+
const ownNameParent = await getHolonName(holosphere, holon);
|
|
24864
24999
|
const parentPropagatePromises = parentHexagons.map(async (parentHexagon) => {
|
|
24865
25000
|
try {
|
|
24866
25001
|
let payloadToPut;
|
|
@@ -24873,8 +25008,9 @@ var HoloSphere = (() => {
|
|
|
24873
25008
|
originalId: data.id,
|
|
24874
25009
|
propagationType: "parent",
|
|
24875
25010
|
// Indicate this is parent propagation
|
|
24876
|
-
parentLevel: holonResolution - getResolution(parentHexagon)
|
|
25011
|
+
parentLevel: holonResolution - getResolution(parentHexagon),
|
|
24877
25012
|
// How many levels up
|
|
25013
|
+
...ownNameParent ? { originName: ownNameParent } : {}
|
|
24878
25014
|
};
|
|
24879
25015
|
if (useHolograms && !isAlreadyHologram) {
|
|
24880
25016
|
const newHologram = holosphere.createHologram(holon, lens, data);
|
|
@@ -24989,60 +25125,64 @@ var HoloSphere = (() => {
|
|
|
24989
25125
|
message: "No federation configuration found for this space"
|
|
24990
25126
|
};
|
|
24991
25127
|
}
|
|
24992
|
-
|
|
24993
|
-
result.
|
|
25128
|
+
const allPartners = fedInfo.federated || [];
|
|
25129
|
+
result.federatedCount = allPartners.length;
|
|
25130
|
+
result.inboundCount = fedInfo.inbound?.length || 0;
|
|
25131
|
+
result.outboundCount = fedInfo.outbound?.length || 0;
|
|
24994
25132
|
const emptyFedInfo = {
|
|
24995
25133
|
id: spaceId,
|
|
24996
25134
|
name: spaceName || spaceId,
|
|
24997
|
-
|
|
24998
|
-
|
|
25135
|
+
federated: [],
|
|
25136
|
+
inbound: [],
|
|
25137
|
+
outbound: [],
|
|
25138
|
+
lensConfig: {},
|
|
25139
|
+
partnerNames: {},
|
|
24999
25140
|
timestamp: Date.now()
|
|
25000
25141
|
};
|
|
25001
25142
|
await holosphere.putGlobal("federation", emptyFedInfo, password);
|
|
25002
|
-
if (notifyPartners &&
|
|
25003
|
-
const updatePromises =
|
|
25143
|
+
if (notifyPartners && allPartners.length > 0) {
|
|
25144
|
+
const updatePromises = allPartners.map(async (partnerSpace) => {
|
|
25004
25145
|
try {
|
|
25005
25146
|
const partnerFedInfo = await getFederation(holosphere, partnerSpace);
|
|
25006
|
-
if (partnerFedInfo)
|
|
25007
|
-
|
|
25008
|
-
|
|
25009
|
-
|
|
25010
|
-
);
|
|
25011
|
-
}
|
|
25012
|
-
if (partnerFedInfo.notify) {
|
|
25013
|
-
partnerFedInfo.notify = partnerFedInfo.notify.filter(
|
|
25014
|
-
(id) => id !== spaceId.toString()
|
|
25015
|
-
);
|
|
25016
|
-
}
|
|
25017
|
-
partnerFedInfo.timestamp = Date.now();
|
|
25018
|
-
await holosphere.putGlobal("federation", partnerFedInfo);
|
|
25019
|
-
result.partnersNotified++;
|
|
25020
|
-
return true;
|
|
25147
|
+
if (!partnerFedInfo) return false;
|
|
25148
|
+
const sid = spaceId.toString();
|
|
25149
|
+
if (partnerFedInfo.federated) {
|
|
25150
|
+
partnerFedInfo.federated = partnerFedInfo.federated.filter((id) => id !== sid);
|
|
25021
25151
|
}
|
|
25022
|
-
|
|
25152
|
+
if (partnerFedInfo.inbound) {
|
|
25153
|
+
partnerFedInfo.inbound = partnerFedInfo.inbound.filter((id) => id !== sid);
|
|
25154
|
+
}
|
|
25155
|
+
if (partnerFedInfo.outbound) {
|
|
25156
|
+
partnerFedInfo.outbound = partnerFedInfo.outbound.filter((id) => id !== sid);
|
|
25157
|
+
}
|
|
25158
|
+
if (partnerFedInfo.lensConfig) {
|
|
25159
|
+
delete partnerFedInfo.lensConfig[sid];
|
|
25160
|
+
}
|
|
25161
|
+
if (partnerFedInfo.partnerNames) {
|
|
25162
|
+
delete partnerFedInfo.partnerNames[sid];
|
|
25163
|
+
}
|
|
25164
|
+
partnerFedInfo.timestamp = Date.now();
|
|
25165
|
+
await holosphere.putGlobal("federation", partnerFedInfo);
|
|
25166
|
+
result.partnersNotified++;
|
|
25167
|
+
return true;
|
|
25023
25168
|
} catch (error) {
|
|
25024
|
-
result.errors.push({
|
|
25025
|
-
partner: partnerSpace,
|
|
25026
|
-
error: error.message
|
|
25027
|
-
});
|
|
25169
|
+
result.errors.push({ partner: partnerSpace, error: error.message });
|
|
25028
25170
|
return false;
|
|
25029
25171
|
}
|
|
25030
25172
|
});
|
|
25031
25173
|
await Promise.all(updatePromises);
|
|
25032
25174
|
}
|
|
25033
|
-
|
|
25034
|
-
|
|
25035
|
-
|
|
25036
|
-
|
|
25037
|
-
|
|
25038
|
-
|
|
25039
|
-
|
|
25040
|
-
|
|
25041
|
-
|
|
25042
|
-
await holosphere.putGlobal("federationMeta", meta);
|
|
25043
|
-
}
|
|
25044
|
-
} catch (error) {
|
|
25175
|
+
for (const partnerSpace of allPartners) {
|
|
25176
|
+
try {
|
|
25177
|
+
const metaId = `${spaceId}_${partnerSpace}`;
|
|
25178
|
+
const altMetaId = `${partnerSpace}_${spaceId}`;
|
|
25179
|
+
const meta = await holosphere.getGlobal("federationMeta", metaId) || await holosphere.getGlobal("federationMeta", altMetaId);
|
|
25180
|
+
if (meta) {
|
|
25181
|
+
meta.status = "inactive";
|
|
25182
|
+
meta.endedAt = Date.now();
|
|
25183
|
+
await holosphere.putGlobal("federationMeta", meta);
|
|
25045
25184
|
}
|
|
25185
|
+
} catch {
|
|
25046
25186
|
}
|
|
25047
25187
|
}
|
|
25048
25188
|
result.success = true;
|
|
@@ -25057,7 +25197,6 @@ var HoloSphere = (() => {
|
|
|
25057
25197
|
}
|
|
25058
25198
|
|
|
25059
25199
|
// schema.js
|
|
25060
|
-
var import__ = __toESM(require__(), 1);
|
|
25061
25200
|
async function setSchema(holoInstance, lens, schema) {
|
|
25062
25201
|
if (!lens || !schema) {
|
|
25063
25202
|
throw new Error("setSchema: Missing required parameters");
|
|
@@ -25139,6 +25278,45 @@ var HoloSphere = (() => {
|
|
|
25139
25278
|
}
|
|
25140
25279
|
|
|
25141
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
|
+
}
|
|
25142
25320
|
async function put(holoInstance, holon, lens, data, password = null, options = {}) {
|
|
25143
25321
|
if (!data) {
|
|
25144
25322
|
throw new Error("put: Missing required data parameter");
|
|
@@ -25236,10 +25414,16 @@ var HoloSphere = (() => {
|
|
|
25236
25414
|
}
|
|
25237
25415
|
return new Promise((resolve, reject) => {
|
|
25238
25416
|
try {
|
|
25239
|
-
|
|
25240
|
-
|
|
25241
|
-
|
|
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
|
+
);
|
|
25242
25424
|
}
|
|
25425
|
+
if (dataToStore._meta !== void 0) delete dataToStore._meta;
|
|
25426
|
+
if (dataToStore._hologram !== void 0) delete dataToStore._hologram;
|
|
25243
25427
|
const payload = JSON.stringify(dataToStore);
|
|
25244
25428
|
const putCallback = async (ack) => {
|
|
25245
25429
|
if (ack.err) {
|
|
@@ -25529,7 +25713,8 @@ var HoloSphere = (() => {
|
|
|
25529
25713
|
const output = /* @__PURE__ */ new Map();
|
|
25530
25714
|
const pendingProcessing = [];
|
|
25531
25715
|
const dataPath = password ? user.get("private").get(lens) : holoInstance.gun.get(holoInstance.appname).get(holon).get(lens);
|
|
25532
|
-
dataPath.once((
|
|
25716
|
+
const shallowOnce = () => new Promise((res) => dataPath.once((d) => res(d)));
|
|
25717
|
+
const processShallow = (data) => {
|
|
25533
25718
|
if (!data) {
|
|
25534
25719
|
resolve([]);
|
|
25535
25720
|
return;
|
|
@@ -25546,72 +25731,75 @@ var HoloSphere = (() => {
|
|
|
25546
25731
|
resolve([]);
|
|
25547
25732
|
return;
|
|
25548
25733
|
}
|
|
25549
|
-
|
|
25550
|
-
|
|
25551
|
-
|
|
25552
|
-
|
|
25553
|
-
if (
|
|
25554
|
-
|
|
25555
|
-
|
|
25556
|
-
|
|
25557
|
-
|
|
25558
|
-
|
|
25559
|
-
|
|
25560
|
-
|
|
25561
|
-
|
|
25562
|
-
|
|
25563
|
-
|
|
25564
|
-
|
|
25565
|
-
|
|
25566
|
-
|
|
25567
|
-
maxDepth: 10,
|
|
25568
|
-
currentDepth: 0
|
|
25569
|
-
});
|
|
25570
|
-
if (resolved === null) {
|
|
25571
|
-
console.warn(`Broken hologram detected in getAll for key ${key}. Removing it...`);
|
|
25572
|
-
try {
|
|
25573
|
-
await holoInstance.delete(holon, lens, key, password);
|
|
25574
|
-
} catch (cleanupError) {
|
|
25575
|
-
console.error(`Failed to remove broken hologram at ${holon}/${lens}/${key}:`, cleanupError);
|
|
25576
|
-
}
|
|
25577
|
-
return;
|
|
25734
|
+
const processItem = async (itemData, key) => {
|
|
25735
|
+
if (!itemData) return;
|
|
25736
|
+
try {
|
|
25737
|
+
const parsed = await holoInstance.parse(itemData);
|
|
25738
|
+
if (!parsed || !parsed.id) return;
|
|
25739
|
+
if (holoInstance.isHologram(parsed)) {
|
|
25740
|
+
try {
|
|
25741
|
+
const resolved = await holoInstance.resolveHologram(parsed, {
|
|
25742
|
+
followHolograms: true,
|
|
25743
|
+
maxDepth: 10,
|
|
25744
|
+
currentDepth: 0
|
|
25745
|
+
});
|
|
25746
|
+
if (resolved === null) {
|
|
25747
|
+
console.warn(`Broken hologram detected in getAll for key ${key}. Removing it...`);
|
|
25748
|
+
try {
|
|
25749
|
+
await holoInstance.delete(holon, lens, key, password);
|
|
25750
|
+
} catch (cleanupError) {
|
|
25751
|
+
console.error(`Failed to remove broken hologram at ${holon}/${lens}/${key}:`, cleanupError);
|
|
25578
25752
|
}
|
|
25579
|
-
|
|
25580
|
-
|
|
25581
|
-
|
|
25582
|
-
|
|
25583
|
-
|
|
25584
|
-
|
|
25585
|
-
} else {
|
|
25753
|
+
return;
|
|
25754
|
+
}
|
|
25755
|
+
if (resolved && resolved !== parsed) {
|
|
25756
|
+
if (schema) {
|
|
25757
|
+
const valid = holoInstance.validator.validate(schema, resolved);
|
|
25758
|
+
if (valid || !holoInstance.strict) {
|
|
25586
25759
|
output.set(resolved.id, resolved);
|
|
25587
25760
|
}
|
|
25588
|
-
|
|
25761
|
+
} else {
|
|
25762
|
+
output.set(resolved.id, resolved);
|
|
25589
25763
|
}
|
|
25590
|
-
} catch (hologramError) {
|
|
25591
|
-
console.error(`Error resolving hologram for key ${key}:`, hologramError);
|
|
25592
25764
|
return;
|
|
25593
25765
|
}
|
|
25766
|
+
} catch (hologramError) {
|
|
25767
|
+
console.error(`Error resolving hologram for key ${key}:`, hologramError);
|
|
25768
|
+
return;
|
|
25594
25769
|
}
|
|
25595
|
-
|
|
25596
|
-
|
|
25597
|
-
|
|
25598
|
-
|
|
25599
|
-
}
|
|
25600
|
-
} else {
|
|
25770
|
+
}
|
|
25771
|
+
if (schema) {
|
|
25772
|
+
const valid = holoInstance.validator.validate(schema, parsed);
|
|
25773
|
+
if (valid || !holoInstance.strict) {
|
|
25601
25774
|
output.set(parsed.id, parsed);
|
|
25602
25775
|
}
|
|
25603
|
-
}
|
|
25604
|
-
|
|
25776
|
+
} else {
|
|
25777
|
+
output.set(parsed.id, parsed);
|
|
25605
25778
|
}
|
|
25606
|
-
}
|
|
25607
|
-
|
|
25608
|
-
receivedCount++;
|
|
25609
|
-
if (receivedCount >= expectedCount) {
|
|
25610
|
-
await Promise.all(pendingProcessing);
|
|
25611
|
-
resolve(Array.from(output.values()));
|
|
25779
|
+
} catch (error) {
|
|
25780
|
+
console.error("Error processing data:", error);
|
|
25612
25781
|
}
|
|
25613
|
-
}
|
|
25614
|
-
|
|
25782
|
+
};
|
|
25783
|
+
Promise.all(keys.map((key) => {
|
|
25784
|
+
const inline = data[key];
|
|
25785
|
+
if (typeof inline !== "object" || inline === null) {
|
|
25786
|
+
return processItem(inline, key);
|
|
25787
|
+
}
|
|
25788
|
+
return new Promise((resolveItem) => {
|
|
25789
|
+
dataPath.get(key).once((itemData) => {
|
|
25790
|
+
processItem(itemData, key).then(resolveItem, resolveItem);
|
|
25791
|
+
});
|
|
25792
|
+
});
|
|
25793
|
+
})).then(() => resolve(Array.from(output.values())));
|
|
25794
|
+
};
|
|
25795
|
+
(async () => {
|
|
25796
|
+
let data = await shallowOnce();
|
|
25797
|
+
if (!data) {
|
|
25798
|
+
await new Promise((r) => setTimeout(r, 1500));
|
|
25799
|
+
data = await shallowOnce();
|
|
25800
|
+
}
|
|
25801
|
+
processShallow(data);
|
|
25802
|
+
})();
|
|
25615
25803
|
});
|
|
25616
25804
|
} catch (error) {
|
|
25617
25805
|
console.error("Error in getAll:", error);
|
|
@@ -26090,6 +26278,9 @@ var HoloSphere = (() => {
|
|
|
26090
26278
|
if (dataToStore._meta !== void 0) {
|
|
26091
26279
|
delete dataToStore._meta;
|
|
26092
26280
|
}
|
|
26281
|
+
if (dataToStore._hologram !== void 0) {
|
|
26282
|
+
delete dataToStore._hologram;
|
|
26283
|
+
}
|
|
26093
26284
|
const payload = JSON.stringify(dataToStore);
|
|
26094
26285
|
const isHologram2 = holoInstance.isHologram(dataToStore);
|
|
26095
26286
|
const dataPath = password ? user.get("private").get(tableName) : holoInstance.gun.get(holoInstance.appname).get(tableName);
|
|
@@ -26290,7 +26481,8 @@ var HoloSphere = (() => {
|
|
|
26290
26481
|
const output = [];
|
|
26291
26482
|
const pendingProcessing = [];
|
|
26292
26483
|
const dataPath = password ? user.get("private").get(tableName) : holoInstance.gun.get(holoInstance.appname).get(tableName);
|
|
26293
|
-
dataPath.once((
|
|
26484
|
+
const shallowOnce = () => new Promise((res) => dataPath.once((d) => res(d)));
|
|
26485
|
+
const processShallow = (data) => {
|
|
26294
26486
|
if (!data) {
|
|
26295
26487
|
resolve([]);
|
|
26296
26488
|
return;
|
|
@@ -26307,52 +26499,55 @@ var HoloSphere = (() => {
|
|
|
26307
26499
|
resolve([]);
|
|
26308
26500
|
return;
|
|
26309
26501
|
}
|
|
26310
|
-
|
|
26311
|
-
|
|
26312
|
-
|
|
26313
|
-
|
|
26314
|
-
if (
|
|
26315
|
-
|
|
26316
|
-
|
|
26317
|
-
|
|
26318
|
-
|
|
26319
|
-
|
|
26320
|
-
|
|
26321
|
-
|
|
26322
|
-
|
|
26323
|
-
|
|
26324
|
-
if (holoInstance.isHologram(parsed)) {
|
|
26325
|
-
const resolved = await holoInstance.resolveHologram(parsed, {
|
|
26326
|
-
followHolograms: true
|
|
26327
|
-
});
|
|
26328
|
-
if (resolved === null) {
|
|
26329
|
-
try {
|
|
26330
|
-
await holoInstance.deleteGlobal(tableName, key, password);
|
|
26331
|
-
} catch (deleteError) {
|
|
26332
|
-
console.error(`Failed to delete invalid global hologram at ${tableName}/${key}:`, deleteError);
|
|
26333
|
-
}
|
|
26334
|
-
return;
|
|
26335
|
-
}
|
|
26336
|
-
if (resolved !== parsed) {
|
|
26337
|
-
output.push(resolved);
|
|
26338
|
-
} else {
|
|
26339
|
-
output.push(parsed);
|
|
26502
|
+
const processItem = async (itemData, key) => {
|
|
26503
|
+
if (!itemData) return;
|
|
26504
|
+
try {
|
|
26505
|
+
const parsed = await holoInstance.parse(itemData);
|
|
26506
|
+
if (!parsed) return;
|
|
26507
|
+
if (holoInstance.isHologram(parsed)) {
|
|
26508
|
+
const resolved = await holoInstance.resolveHologram(parsed, {
|
|
26509
|
+
followHolograms: true
|
|
26510
|
+
});
|
|
26511
|
+
if (resolved === null) {
|
|
26512
|
+
try {
|
|
26513
|
+
await holoInstance.deleteGlobal(tableName, key, password);
|
|
26514
|
+
} catch (deleteError) {
|
|
26515
|
+
console.error(`Failed to delete invalid global hologram at ${tableName}/${key}:`, deleteError);
|
|
26340
26516
|
}
|
|
26517
|
+
return;
|
|
26518
|
+
}
|
|
26519
|
+
if (resolved !== parsed) {
|
|
26520
|
+
output.push(resolved);
|
|
26341
26521
|
} else {
|
|
26342
26522
|
output.push(parsed);
|
|
26343
26523
|
}
|
|
26344
|
-
}
|
|
26345
|
-
|
|
26524
|
+
} else {
|
|
26525
|
+
output.push(parsed);
|
|
26346
26526
|
}
|
|
26347
|
-
}
|
|
26348
|
-
|
|
26349
|
-
receivedCount++;
|
|
26350
|
-
if (receivedCount >= expectedCount) {
|
|
26351
|
-
await Promise.all(pendingProcessing);
|
|
26352
|
-
resolve(output);
|
|
26527
|
+
} catch (error) {
|
|
26528
|
+
console.error("Error parsing data:", error);
|
|
26353
26529
|
}
|
|
26354
|
-
}
|
|
26355
|
-
|
|
26530
|
+
};
|
|
26531
|
+
Promise.all(keys.map((key) => {
|
|
26532
|
+
const inline = data[key];
|
|
26533
|
+
if (typeof inline !== "object" || inline === null) {
|
|
26534
|
+
return processItem(inline, key);
|
|
26535
|
+
}
|
|
26536
|
+
return new Promise((resolveItem) => {
|
|
26537
|
+
dataPath.get(key).once((itemData) => {
|
|
26538
|
+
processItem(itemData, key).then(resolveItem, resolveItem);
|
|
26539
|
+
});
|
|
26540
|
+
});
|
|
26541
|
+
})).then(() => resolve(output));
|
|
26542
|
+
};
|
|
26543
|
+
(async () => {
|
|
26544
|
+
let data = await shallowOnce();
|
|
26545
|
+
if (!data) {
|
|
26546
|
+
await new Promise((r) => setTimeout(r, 1500));
|
|
26547
|
+
data = await shallowOnce();
|
|
26548
|
+
}
|
|
26549
|
+
processShallow(data);
|
|
26550
|
+
})();
|
|
26356
26551
|
});
|
|
26357
26552
|
} catch (error) {
|
|
26358
26553
|
console.error("Error in getAllGlobal:", error);
|
|
@@ -26642,116 +26837,6 @@ var HoloSphere = (() => {
|
|
|
26642
26837
|
};
|
|
26643
26838
|
}
|
|
26644
26839
|
|
|
26645
|
-
// hologram.js
|
|
26646
|
-
function createHologram(holoInstance, holon, lens, data) {
|
|
26647
|
-
if (isHologram(data)) {
|
|
26648
|
-
return {
|
|
26649
|
-
id: data.id,
|
|
26650
|
-
soul: data.soul
|
|
26651
|
-
};
|
|
26652
|
-
}
|
|
26653
|
-
if (!holon || !lens || !data || !data.id) {
|
|
26654
|
-
throw new Error("createHologram: Missing required parameters for non-hologram data");
|
|
26655
|
-
}
|
|
26656
|
-
const soul = `${holoInstance.appname}/${holon}/${lens}/${data.id}`;
|
|
26657
|
-
return {
|
|
26658
|
-
id: data.id,
|
|
26659
|
-
soul
|
|
26660
|
-
};
|
|
26661
|
-
}
|
|
26662
|
-
function parseSoulPath(soul) {
|
|
26663
|
-
if (typeof soul !== "string") return null;
|
|
26664
|
-
const parts = soul.split("/");
|
|
26665
|
-
if (parts.length < 4) return null;
|
|
26666
|
-
const key = parts.slice(3).join("/");
|
|
26667
|
-
return {
|
|
26668
|
-
appname: parts[0],
|
|
26669
|
-
holon: parts[1],
|
|
26670
|
-
lens: parts[2],
|
|
26671
|
-
key
|
|
26672
|
-
};
|
|
26673
|
-
}
|
|
26674
|
-
function isHologram(data) {
|
|
26675
|
-
if (!data || typeof data !== "object") {
|
|
26676
|
-
return false;
|
|
26677
|
-
}
|
|
26678
|
-
if (data.id && typeof data.soul === "string" && data.soul.length > 0) {
|
|
26679
|
-
if (data.soul.includes("/")) {
|
|
26680
|
-
return true;
|
|
26681
|
-
}
|
|
26682
|
-
}
|
|
26683
|
-
return false;
|
|
26684
|
-
}
|
|
26685
|
-
async function resolveHologram(holoInstance, hologram, options = {}) {
|
|
26686
|
-
if (!isHologram(hologram)) {
|
|
26687
|
-
return hologram;
|
|
26688
|
-
}
|
|
26689
|
-
const {
|
|
26690
|
-
followHolograms = true,
|
|
26691
|
-
visited = /* @__PURE__ */ new Set(),
|
|
26692
|
-
maxDepth = 10,
|
|
26693
|
-
currentDepth = 0
|
|
26694
|
-
} = options;
|
|
26695
|
-
if (currentDepth >= maxDepth) {
|
|
26696
|
-
console.warn(`!!! Maximum resolution depth (${maxDepth}) reached for soul: ${hologram.soul}. Stopping resolution.`);
|
|
26697
|
-
return null;
|
|
26698
|
-
}
|
|
26699
|
-
if (hologram.soul && visited.has(hologram.soul)) {
|
|
26700
|
-
console.warn(`!!! CIRCULAR hologram detected for soul: ${hologram.soul}. Breaking loop.`);
|
|
26701
|
-
return null;
|
|
26702
|
-
}
|
|
26703
|
-
try {
|
|
26704
|
-
if (hologram.soul) {
|
|
26705
|
-
const soulInfo = parseSoulPath(hologram.soul);
|
|
26706
|
-
if (!soulInfo) {
|
|
26707
|
-
console.warn(`Invalid soul format: ${hologram.soul}`);
|
|
26708
|
-
return null;
|
|
26709
|
-
}
|
|
26710
|
-
const nextVisited = new Set(visited);
|
|
26711
|
-
nextVisited.add(hologram.soul);
|
|
26712
|
-
const originalData = await holoInstance.get(
|
|
26713
|
-
soulInfo.holon,
|
|
26714
|
-
soulInfo.lens,
|
|
26715
|
-
soulInfo.key,
|
|
26716
|
-
null,
|
|
26717
|
-
{
|
|
26718
|
-
resolveHolograms: followHolograms,
|
|
26719
|
-
visited: nextVisited,
|
|
26720
|
-
maxDepth,
|
|
26721
|
-
currentDepth: currentDepth + 1
|
|
26722
|
-
}
|
|
26723
|
-
);
|
|
26724
|
-
if (originalData && !originalData._invalidHologram) {
|
|
26725
|
-
return {
|
|
26726
|
-
...originalData,
|
|
26727
|
-
_meta: {
|
|
26728
|
-
...originalData._meta || {},
|
|
26729
|
-
// Preserve original _meta
|
|
26730
|
-
resolvedFromHologram: true,
|
|
26731
|
-
// This is now the primary indicator
|
|
26732
|
-
hologramSoul: hologram.soul,
|
|
26733
|
-
// Clarified meta field
|
|
26734
|
-
resolutionDepth: currentDepth
|
|
26735
|
-
}
|
|
26736
|
-
};
|
|
26737
|
-
} else {
|
|
26738
|
-
console.warn(`!!! Original data NOT FOUND for soul: ${hologram.soul}. Removing broken hologram.`);
|
|
26739
|
-
return null;
|
|
26740
|
-
}
|
|
26741
|
-
} else {
|
|
26742
|
-
console.warn("!!! resolveHologram called with object missing soul:", hologram);
|
|
26743
|
-
return null;
|
|
26744
|
-
}
|
|
26745
|
-
} catch (error) {
|
|
26746
|
-
if (error.message?.startsWith("CIRCULAR_REFERENCE")) {
|
|
26747
|
-
console.warn(`!!! Circular reference detected during hologram resolution: ${error.message}`);
|
|
26748
|
-
return null;
|
|
26749
|
-
}
|
|
26750
|
-
console.error(`!!! Error resolving hologram: ${error.message}`, error);
|
|
26751
|
-
return null;
|
|
26752
|
-
}
|
|
26753
|
-
}
|
|
26754
|
-
|
|
26755
26840
|
// compute.js
|
|
26756
26841
|
async function computeHierarchy(holoInstance, holon, lens, options, maxLevels = 15, password = null) {
|
|
26757
26842
|
let currentHolon = holon;
|
|
@@ -30225,7 +30310,7 @@ var HoloSphere = (() => {
|
|
|
30225
30310
|
this._privateKey = null;
|
|
30226
30311
|
}
|
|
30227
30312
|
console.log("HoloSphere v" + HOLOSPHERE_VERSION);
|
|
30228
|
-
this.validator = new
|
|
30313
|
+
this.validator = new import__.default({
|
|
30229
30314
|
allErrors: true,
|
|
30230
30315
|
strict: false,
|
|
30231
30316
|
validateSchema: true
|
|
@@ -30377,6 +30462,9 @@ var HoloSphere = (() => {
|
|
|
30377
30462
|
async resolveHologram(hologram, options = {}) {
|
|
30378
30463
|
return resolveHologram(this, hologram, options);
|
|
30379
30464
|
}
|
|
30465
|
+
attachHologramMeta(originalData, hologramSoul) {
|
|
30466
|
+
return attachHologramMeta(originalData, hologramSoul);
|
|
30467
|
+
}
|
|
30380
30468
|
// ================================ COMPUTE FUNCTIONS ================================
|
|
30381
30469
|
async computeHierarchy(holon, lens, options, maxLevels = 15, password = null) {
|
|
30382
30470
|
return computeHierarchy(this, holon, lens, options, maxLevels, password);
|
|
@@ -30419,41 +30507,37 @@ var HoloSphere = (() => {
|
|
|
30419
30507
|
return federate(this, holonId1, holonId2, password1, password2, bidirectional, lensConfig);
|
|
30420
30508
|
}
|
|
30421
30509
|
/**
|
|
30422
|
-
*
|
|
30423
|
-
* Maps v2 options to v1 federate() call.
|
|
30510
|
+
* Convenience wrapper around federate() for the common bidirectional case.
|
|
30424
30511
|
* @param {string} sourceHolon - Source holon ID
|
|
30425
30512
|
* @param {string} targetHolon - Target holon ID
|
|
30426
30513
|
* @param {object} [options] - Federation options
|
|
30427
|
-
* @param {object} [options.lensConfig] - Lens
|
|
30428
|
-
* @param {string} [options.
|
|
30429
|
-
* @param {
|
|
30514
|
+
* @param {object} [options.lensConfig] - Lens config from sourceHolon's perspective
|
|
30515
|
+
* @param {string[]} [options.lensConfig.inbound] - Lenses sourceHolon receives from targetHolon
|
|
30516
|
+
* @param {string[]} [options.lensConfig.outbound] - Lenses sourceHolon sends to targetHolon
|
|
30517
|
+
* @param {string} [options.partnerName] - Display name for the partner
|
|
30430
30518
|
* @returns {Promise<boolean>}
|
|
30431
30519
|
*/
|
|
30432
30520
|
async federateHolon(sourceHolon, targetHolon, options = {}) {
|
|
30433
30521
|
const lensConfig = options.lensConfig || {};
|
|
30434
|
-
const
|
|
30435
|
-
|
|
30522
|
+
const inbound = Array.isArray(lensConfig.inbound) ? lensConfig.inbound : [];
|
|
30523
|
+
const outbound = Array.isArray(lensConfig.outbound) ? lensConfig.outbound : [];
|
|
30524
|
+
const ok = await federate(this, sourceHolon, targetHolon, null, null, true, {
|
|
30525
|
+
inbound,
|
|
30526
|
+
outbound
|
|
30527
|
+
});
|
|
30528
|
+
if (ok && options.partnerName) {
|
|
30436
30529
|
try {
|
|
30437
|
-
const fedInfo = await this.getFederation(sourceHolon)
|
|
30438
|
-
|
|
30439
|
-
|
|
30440
|
-
|
|
30441
|
-
|
|
30442
|
-
|
|
30443
|
-
partnerNames: {},
|
|
30444
|
-
timestamp: Date.now()
|
|
30445
|
-
};
|
|
30446
|
-
if (!fedInfo.partnerNames) fedInfo.partnerNames = {};
|
|
30447
|
-
fedInfo.partnerNames[targetHolon] = options.partnerName;
|
|
30448
|
-
await this.putGlobal("federation", fedInfo);
|
|
30530
|
+
const fedInfo = await this.getFederation(sourceHolon);
|
|
30531
|
+
if (fedInfo) {
|
|
30532
|
+
if (!fedInfo.partnerNames) fedInfo.partnerNames = {};
|
|
30533
|
+
fedInfo.partnerNames[targetHolon] = options.partnerName;
|
|
30534
|
+
await this.putGlobal("federation", fedInfo);
|
|
30535
|
+
}
|
|
30449
30536
|
} catch (e) {
|
|
30450
30537
|
console.warn("Failed to store partner name:", e.message);
|
|
30451
30538
|
}
|
|
30452
30539
|
}
|
|
30453
|
-
return
|
|
30454
|
-
federate: lenses,
|
|
30455
|
-
notify: lenses
|
|
30456
|
-
});
|
|
30540
|
+
return ok;
|
|
30457
30541
|
}
|
|
30458
30542
|
/**
|
|
30459
30543
|
* v2-compatible federation removal.
|