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.esm.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* HoloSphere ESM Bundle v1.3.0-
|
|
2
|
+
* HoloSphere ESM Bundle v1.3.0-alpha4
|
|
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-
|
|
6
|
+
* import HoloSphere from 'https://unpkg.com/holosphere@1.3.0-alpha4/holosphere-bundle.esm.js';
|
|
7
7
|
* const hs = new HoloSphere('myapp');
|
|
8
8
|
*/
|
|
9
9
|
var __create = Object.create;
|
|
@@ -7054,7 +7054,7 @@ var require_core = __commonJS({
|
|
|
7054
7054
|
constructor(opts = {}) {
|
|
7055
7055
|
this.schemas = {};
|
|
7056
7056
|
this.refs = {};
|
|
7057
|
-
this.formats =
|
|
7057
|
+
this.formats = /* @__PURE__ */ Object.create(null);
|
|
7058
7058
|
this._compilations = /* @__PURE__ */ new Set();
|
|
7059
7059
|
this._loading = {};
|
|
7060
7060
|
this._cache = /* @__PURE__ */ new Map();
|
|
@@ -7835,6 +7835,7 @@ var require_pattern = __commonJS({
|
|
|
7835
7835
|
"use strict";
|
|
7836
7836
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7837
7837
|
var code_1 = require_code2();
|
|
7838
|
+
var util_1 = require_util();
|
|
7838
7839
|
var codegen_1 = require_codegen();
|
|
7839
7840
|
var error = {
|
|
7840
7841
|
message: ({ schemaCode }) => (0, codegen_1.str)`must match pattern "${schemaCode}"`,
|
|
@@ -7847,10 +7848,18 @@ var require_pattern = __commonJS({
|
|
|
7847
7848
|
$data: true,
|
|
7848
7849
|
error,
|
|
7849
7850
|
code(cxt) {
|
|
7850
|
-
const { data, $data, schema, schemaCode, it } = cxt;
|
|
7851
|
+
const { gen, data, $data, schema, schemaCode, it } = cxt;
|
|
7851
7852
|
const u = it.opts.unicodeRegExp ? "u" : "";
|
|
7852
|
-
|
|
7853
|
-
|
|
7853
|
+
if ($data) {
|
|
7854
|
+
const { regExp } = it.opts.code;
|
|
7855
|
+
const regExpCode = regExp.code === "new RegExp" ? (0, codegen_1._)`new RegExp` : (0, util_1.useFunc)(gen, regExp);
|
|
7856
|
+
const valid = gen.let("valid");
|
|
7857
|
+
gen.try(() => gen.assign(valid, (0, codegen_1._)`${regExpCode}(${schemaCode}, ${u}).test(${data})`), () => gen.assign(valid, false));
|
|
7858
|
+
cxt.fail$data((0, codegen_1._)`!${valid}`);
|
|
7859
|
+
} else {
|
|
7860
|
+
const regExp = (0, code_1.usePattern)(cxt, schema);
|
|
7861
|
+
cxt.fail$data((0, codegen_1._)`!${regExp}.test(${data})`);
|
|
7862
|
+
}
|
|
7854
7863
|
}
|
|
7855
7864
|
};
|
|
7856
7865
|
exports.default = def;
|
|
@@ -10061,7 +10070,7 @@ var require__ = __commonJS({
|
|
|
10061
10070
|
var discriminator_1 = require_discriminator();
|
|
10062
10071
|
var json_schema_2019_09_1 = require_json_schema_2019_09();
|
|
10063
10072
|
var META_SCHEMA_ID = "https://json-schema.org/draft/2019-09/schema";
|
|
10064
|
-
var
|
|
10073
|
+
var Ajv20192 = class extends core_1.default {
|
|
10065
10074
|
constructor(opts = {}) {
|
|
10066
10075
|
super({
|
|
10067
10076
|
...opts,
|
|
@@ -10091,11 +10100,11 @@ var require__ = __commonJS({
|
|
|
10091
10100
|
return this.opts.defaultMeta = super.defaultMeta() || (this.getSchema(META_SCHEMA_ID) ? META_SCHEMA_ID : void 0);
|
|
10092
10101
|
}
|
|
10093
10102
|
};
|
|
10094
|
-
exports.Ajv2019 =
|
|
10095
|
-
module.exports = exports =
|
|
10096
|
-
module.exports.Ajv2019 =
|
|
10103
|
+
exports.Ajv2019 = Ajv20192;
|
|
10104
|
+
module.exports = exports = Ajv20192;
|
|
10105
|
+
module.exports.Ajv2019 = Ajv20192;
|
|
10097
10106
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10098
|
-
exports.default =
|
|
10107
|
+
exports.default = Ajv20192;
|
|
10099
10108
|
var validate_1 = require_validate();
|
|
10100
10109
|
Object.defineProperty(exports, "KeywordCxt", { enumerable: true, get: function() {
|
|
10101
10110
|
return validate_1.KeywordCxt;
|
|
@@ -24197,9 +24206,139 @@ function degsToRads(deg) {
|
|
|
24197
24206
|
|
|
24198
24207
|
// holosphere.js
|
|
24199
24208
|
var import_gun = __toESM(require_browser(), 1);
|
|
24200
|
-
var
|
|
24209
|
+
var import__ = __toESM(require__(), 1);
|
|
24210
|
+
|
|
24211
|
+
// hologram.js
|
|
24212
|
+
function createHologram(holoInstance, holon, lens, data) {
|
|
24213
|
+
if (isHologram(data)) {
|
|
24214
|
+
return {
|
|
24215
|
+
id: data.id,
|
|
24216
|
+
soul: data.soul
|
|
24217
|
+
};
|
|
24218
|
+
}
|
|
24219
|
+
if (!holon || !lens || !data || !data.id) {
|
|
24220
|
+
throw new Error("createHologram: Missing required parameters for non-hologram data");
|
|
24221
|
+
}
|
|
24222
|
+
const soul = `${holoInstance.appname}/${holon}/${lens}/${data.id}`;
|
|
24223
|
+
return {
|
|
24224
|
+
id: data.id,
|
|
24225
|
+
soul
|
|
24226
|
+
};
|
|
24227
|
+
}
|
|
24228
|
+
function parseSoulPath(soul) {
|
|
24229
|
+
if (typeof soul !== "string") return null;
|
|
24230
|
+
const parts = soul.split("/");
|
|
24231
|
+
if (parts.length < 4) return null;
|
|
24232
|
+
const key = parts.slice(3).join("/");
|
|
24233
|
+
return {
|
|
24234
|
+
appname: parts[0],
|
|
24235
|
+
holon: parts[1],
|
|
24236
|
+
lens: parts[2],
|
|
24237
|
+
key
|
|
24238
|
+
};
|
|
24239
|
+
}
|
|
24240
|
+
function isHologram(data) {
|
|
24241
|
+
if (!data || typeof data !== "object") {
|
|
24242
|
+
return false;
|
|
24243
|
+
}
|
|
24244
|
+
if (data.id && typeof data.soul === "string" && data.soul.length > 0) {
|
|
24245
|
+
if (data.soul.includes("/")) {
|
|
24246
|
+
return true;
|
|
24247
|
+
}
|
|
24248
|
+
}
|
|
24249
|
+
return false;
|
|
24250
|
+
}
|
|
24251
|
+
function attachHologramMeta(originalData, hologramSoul) {
|
|
24252
|
+
const parts = parseSoulPath(hologramSoul);
|
|
24253
|
+
return {
|
|
24254
|
+
...originalData,
|
|
24255
|
+
_hologram: {
|
|
24256
|
+
isHologram: true,
|
|
24257
|
+
soul: hologramSoul,
|
|
24258
|
+
sourceHolon: parts?.holon ?? null,
|
|
24259
|
+
sourceLens: parts?.lens ?? null,
|
|
24260
|
+
sourceKey: parts?.key ?? null,
|
|
24261
|
+
resolvedAt: Date.now()
|
|
24262
|
+
}
|
|
24263
|
+
};
|
|
24264
|
+
}
|
|
24265
|
+
async function resolveHologram(holoInstance, hologram, options = {}) {
|
|
24266
|
+
if (!isHologram(hologram)) {
|
|
24267
|
+
return hologram;
|
|
24268
|
+
}
|
|
24269
|
+
const {
|
|
24270
|
+
followHolograms = true,
|
|
24271
|
+
visited = /* @__PURE__ */ new Set(),
|
|
24272
|
+
maxDepth = 10,
|
|
24273
|
+
currentDepth = 0
|
|
24274
|
+
} = options;
|
|
24275
|
+
if (currentDepth >= maxDepth) {
|
|
24276
|
+
console.warn(`!!! Maximum resolution depth (${maxDepth}) reached for soul: ${hologram.soul}. Stopping resolution.`);
|
|
24277
|
+
return null;
|
|
24278
|
+
}
|
|
24279
|
+
if (hologram.soul && visited.has(hologram.soul)) {
|
|
24280
|
+
console.warn(`!!! CIRCULAR hologram detected for soul: ${hologram.soul}. Breaking loop.`);
|
|
24281
|
+
return null;
|
|
24282
|
+
}
|
|
24283
|
+
try {
|
|
24284
|
+
if (hologram.soul) {
|
|
24285
|
+
const soulInfo = parseSoulPath(hologram.soul);
|
|
24286
|
+
if (!soulInfo) {
|
|
24287
|
+
console.warn(`Invalid soul format: ${hologram.soul}`);
|
|
24288
|
+
return null;
|
|
24289
|
+
}
|
|
24290
|
+
const nextVisited = new Set(visited);
|
|
24291
|
+
nextVisited.add(hologram.soul);
|
|
24292
|
+
const originalData = await holoInstance.get(
|
|
24293
|
+
soulInfo.holon,
|
|
24294
|
+
soulInfo.lens,
|
|
24295
|
+
soulInfo.key,
|
|
24296
|
+
null,
|
|
24297
|
+
{
|
|
24298
|
+
resolveHolograms: followHolograms,
|
|
24299
|
+
visited: nextVisited,
|
|
24300
|
+
maxDepth,
|
|
24301
|
+
currentDepth: currentDepth + 1
|
|
24302
|
+
}
|
|
24303
|
+
);
|
|
24304
|
+
if (originalData && !originalData._invalidHologram) {
|
|
24305
|
+
return attachHologramMeta(originalData, hologram.soul);
|
|
24306
|
+
} else {
|
|
24307
|
+
console.warn(`!!! Original data NOT FOUND for soul: ${hologram.soul}. Removing broken hologram.`);
|
|
24308
|
+
return null;
|
|
24309
|
+
}
|
|
24310
|
+
} else {
|
|
24311
|
+
console.warn("!!! resolveHologram called with object missing soul:", hologram);
|
|
24312
|
+
return null;
|
|
24313
|
+
}
|
|
24314
|
+
} catch (error) {
|
|
24315
|
+
if (error.message?.startsWith("CIRCULAR_REFERENCE")) {
|
|
24316
|
+
console.warn(`!!! Circular reference detected during hologram resolution: ${error.message}`);
|
|
24317
|
+
return null;
|
|
24318
|
+
}
|
|
24319
|
+
console.error(`!!! Error resolving hologram: ${error.message}`, error);
|
|
24320
|
+
return null;
|
|
24321
|
+
}
|
|
24322
|
+
}
|
|
24201
24323
|
|
|
24202
24324
|
// federation.js
|
|
24325
|
+
async function getHolonName(holosphere, space) {
|
|
24326
|
+
if (!holosphere || !space) return null;
|
|
24327
|
+
try {
|
|
24328
|
+
const settings = await holosphere.get(space, "settings", space);
|
|
24329
|
+
if (!settings) return null;
|
|
24330
|
+
if (Array.isArray(settings)) {
|
|
24331
|
+
const found = settings.find((s) => s && typeof s.name === "string" && s.name.trim() !== "");
|
|
24332
|
+
return found ? found.name : null;
|
|
24333
|
+
}
|
|
24334
|
+
if (typeof settings.name === "string" && settings.name.trim() !== "") {
|
|
24335
|
+
return settings.name;
|
|
24336
|
+
}
|
|
24337
|
+
return null;
|
|
24338
|
+
} catch {
|
|
24339
|
+
return null;
|
|
24340
|
+
}
|
|
24341
|
+
}
|
|
24203
24342
|
async function federate(holosphere, spaceId1, spaceId2, password1 = null, password2 = null, bidirectional = true, lensConfig = {}) {
|
|
24204
24343
|
if (!spaceId1 || !spaceId2) {
|
|
24205
24344
|
throw new Error("federate: Missing required space IDs");
|
|
@@ -24207,110 +24346,85 @@ async function federate(holosphere, spaceId1, spaceId2, password1 = null, passwo
|
|
|
24207
24346
|
if (spaceId1 === spaceId2) {
|
|
24208
24347
|
throw new Error("Cannot federate a space with itself");
|
|
24209
24348
|
}
|
|
24210
|
-
const {
|
|
24211
|
-
if (!Array.isArray(
|
|
24212
|
-
throw new Error("federate: lensConfig.
|
|
24213
|
-
}
|
|
24214
|
-
const
|
|
24215
|
-
|
|
24349
|
+
const { inbound = [], outbound = [] } = lensConfig;
|
|
24350
|
+
if (!Array.isArray(inbound) || !Array.isArray(outbound)) {
|
|
24351
|
+
throw new Error("federate: lensConfig.inbound and lensConfig.outbound must be arrays");
|
|
24352
|
+
}
|
|
24353
|
+
const applyDirection = (fedInfo, partnerId, partnerInbound, partnerOutbound) => {
|
|
24354
|
+
if (!fedInfo.federated) fedInfo.federated = [];
|
|
24355
|
+
if (!fedInfo.inbound) fedInfo.inbound = [];
|
|
24356
|
+
if (!fedInfo.outbound) fedInfo.outbound = [];
|
|
24357
|
+
if (!fedInfo.lensConfig) fedInfo.lensConfig = {};
|
|
24358
|
+
if (!fedInfo.federated.includes(partnerId)) {
|
|
24359
|
+
fedInfo.federated.push(partnerId);
|
|
24360
|
+
}
|
|
24361
|
+
const hasInbound = partnerInbound.length > 0;
|
|
24362
|
+
const hasOutbound = partnerOutbound.length > 0;
|
|
24363
|
+
if (hasInbound && !fedInfo.inbound.includes(partnerId)) {
|
|
24364
|
+
fedInfo.inbound.push(partnerId);
|
|
24365
|
+
} else if (!hasInbound) {
|
|
24366
|
+
fedInfo.inbound = fedInfo.inbound.filter((id) => id !== partnerId);
|
|
24367
|
+
}
|
|
24368
|
+
if (hasOutbound && !fedInfo.outbound.includes(partnerId)) {
|
|
24369
|
+
fedInfo.outbound.push(partnerId);
|
|
24370
|
+
} else if (!hasOutbound) {
|
|
24371
|
+
fedInfo.outbound = fedInfo.outbound.filter((id) => id !== partnerId);
|
|
24372
|
+
}
|
|
24373
|
+
fedInfo.lensConfig[partnerId] = {
|
|
24374
|
+
inbound: [...partnerInbound],
|
|
24375
|
+
outbound: [...partnerOutbound],
|
|
24376
|
+
timestamp: Date.now()
|
|
24377
|
+
};
|
|
24378
|
+
fedInfo.timestamp = Date.now();
|
|
24379
|
+
};
|
|
24216
24380
|
try {
|
|
24217
24381
|
let fedInfo1 = null;
|
|
24218
24382
|
try {
|
|
24219
24383
|
fedInfo1 = await holosphere.getGlobal("federation", spaceId1, password1);
|
|
24220
|
-
} catch
|
|
24384
|
+
} catch {
|
|
24221
24385
|
}
|
|
24222
24386
|
if (fedInfo1 == null) {
|
|
24223
24387
|
fedInfo1 = {
|
|
24224
24388
|
id: spaceId1,
|
|
24225
24389
|
name: spaceId1,
|
|
24226
|
-
|
|
24227
|
-
|
|
24390
|
+
federated: [],
|
|
24391
|
+
inbound: [],
|
|
24392
|
+
outbound: [],
|
|
24228
24393
|
lensConfig: {},
|
|
24229
|
-
|
|
24394
|
+
partnerNames: {},
|
|
24230
24395
|
timestamp: Date.now()
|
|
24231
24396
|
};
|
|
24232
24397
|
}
|
|
24233
|
-
|
|
24234
|
-
if (!fedInfo1.notify) fedInfo1.notify = [];
|
|
24235
|
-
if (!fedInfo1.lensConfig) fedInfo1.lensConfig = {};
|
|
24236
|
-
if (!fedInfo1.federation.includes(spaceId2)) {
|
|
24237
|
-
fedInfo1.federation.push(spaceId2);
|
|
24238
|
-
}
|
|
24239
|
-
if (!fedInfo1.notify.includes(spaceId2)) {
|
|
24240
|
-
fedInfo1.notify.push(spaceId2);
|
|
24241
|
-
}
|
|
24242
|
-
const newLensConfigsForSpace1 = { ...fedInfo1.lensConfig || {} };
|
|
24243
|
-
newLensConfigsForSpace1[spaceId2] = {
|
|
24244
|
-
// Add/update config for the target spaceId2
|
|
24245
|
-
federate: [...federateLenses],
|
|
24246
|
-
// federateLenses & notifyLenses are from the main lensConfig parameter
|
|
24247
|
-
notify: [...notifyLenses],
|
|
24248
|
-
timestamp: Date.now()
|
|
24249
|
-
};
|
|
24250
|
-
fedInfo1.lensConfig = newLensConfigsForSpace1;
|
|
24251
|
-
fedInfo1.timestamp = Date.now();
|
|
24398
|
+
applyDirection(fedInfo1, spaceId2, inbound, outbound);
|
|
24252
24399
|
try {
|
|
24253
24400
|
await holosphere.putGlobal("federation", fedInfo1, password1);
|
|
24254
24401
|
} catch (error) {
|
|
24255
24402
|
throw new Error(`Failed to create federation: ${error.message}`);
|
|
24256
24403
|
}
|
|
24257
|
-
{
|
|
24404
|
+
if (bidirectional) {
|
|
24258
24405
|
let fedInfo2 = null;
|
|
24259
24406
|
try {
|
|
24260
24407
|
fedInfo2 = await holosphere.getGlobal("federation", spaceId2, password2);
|
|
24261
|
-
} catch
|
|
24408
|
+
} catch {
|
|
24262
24409
|
}
|
|
24263
24410
|
if (fedInfo2 == null) {
|
|
24264
24411
|
fedInfo2 = {
|
|
24265
24412
|
id: spaceId2,
|
|
24266
24413
|
name: spaceId2,
|
|
24267
|
-
|
|
24268
|
-
|
|
24414
|
+
federated: [],
|
|
24415
|
+
inbound: [],
|
|
24416
|
+
outbound: [],
|
|
24269
24417
|
lensConfig: {},
|
|
24270
|
-
|
|
24418
|
+
partnerNames: {},
|
|
24271
24419
|
timestamp: Date.now()
|
|
24272
24420
|
};
|
|
24273
24421
|
}
|
|
24274
|
-
|
|
24275
|
-
if (!fedInfo2.notify) fedInfo2.notify = [];
|
|
24276
|
-
if (!fedInfo2.lensConfig) fedInfo2.lensConfig = {};
|
|
24277
|
-
if (bidirectional && !fedInfo2.federation.includes(spaceId1)) {
|
|
24278
|
-
fedInfo2.federation.push(spaceId1);
|
|
24279
|
-
}
|
|
24280
|
-
if (!fedInfo2.notify.includes(spaceId1)) {
|
|
24281
|
-
fedInfo2.notify.push(spaceId1);
|
|
24282
|
-
}
|
|
24283
|
-
fedInfo2.lensConfig[spaceId1] = {
|
|
24284
|
-
federate: bidirectional ? [...federateLenses] : [],
|
|
24285
|
-
// Create a copy of the array
|
|
24286
|
-
notify: bidirectional ? [...notifyLenses] : [],
|
|
24287
|
-
// Create a copy of the array
|
|
24288
|
-
timestamp: Date.now()
|
|
24289
|
-
};
|
|
24290
|
-
fedInfo2.timestamp = Date.now();
|
|
24422
|
+
applyDirection(fedInfo2, spaceId1, outbound, inbound);
|
|
24291
24423
|
try {
|
|
24292
24424
|
await holosphere.putGlobal("federation", fedInfo2, password2);
|
|
24293
|
-
} catch
|
|
24425
|
+
} catch {
|
|
24294
24426
|
}
|
|
24295
24427
|
}
|
|
24296
|
-
const federationMeta = {
|
|
24297
|
-
id: `${spaceId1}_${spaceId2}`,
|
|
24298
|
-
space1: spaceId1,
|
|
24299
|
-
space2: spaceId2,
|
|
24300
|
-
created: Date.now(),
|
|
24301
|
-
status: "active",
|
|
24302
|
-
bidirectional,
|
|
24303
|
-
lensConfig: {
|
|
24304
|
-
federate: [...federateLenses],
|
|
24305
|
-
// Create a copy of the array
|
|
24306
|
-
notify: [...notifyLenses]
|
|
24307
|
-
// Create a copy of the array
|
|
24308
|
-
}
|
|
24309
|
-
};
|
|
24310
|
-
try {
|
|
24311
|
-
await holosphere.putGlobal("federationMeta", federationMeta);
|
|
24312
|
-
} catch (error) {
|
|
24313
|
-
}
|
|
24314
24428
|
return true;
|
|
24315
24429
|
} catch (error) {
|
|
24316
24430
|
throw error;
|
|
@@ -24327,8 +24441,15 @@ async function subscribeFederation(holosphere, spaceId, password = null, callbac
|
|
|
24327
24441
|
}
|
|
24328
24442
|
const subscriptions2 = [];
|
|
24329
24443
|
let lastNotificationTime = {};
|
|
24330
|
-
|
|
24331
|
-
|
|
24444
|
+
const partnerNames = /* @__PURE__ */ new Map();
|
|
24445
|
+
if (fedInfo.inbound && fedInfo.inbound.length > 0) {
|
|
24446
|
+
await Promise.all(
|
|
24447
|
+
fedInfo.inbound.map(async (space) => {
|
|
24448
|
+
const name = await getHolonName(holosphere, space);
|
|
24449
|
+
partnerNames.set(space, name);
|
|
24450
|
+
})
|
|
24451
|
+
);
|
|
24452
|
+
for (const federatedSpace of fedInfo.inbound) {
|
|
24332
24453
|
for (const lens of lenses) {
|
|
24333
24454
|
try {
|
|
24334
24455
|
const sub = await holosphere.subscribe(federatedSpace, lens, async (data) => {
|
|
@@ -24342,10 +24463,13 @@ async function subscribeFederation(holosphere, spaceId, password = null, callbac
|
|
|
24342
24463
|
}
|
|
24343
24464
|
lastNotificationTime[key] = now;
|
|
24344
24465
|
}
|
|
24345
|
-
if (!data.
|
|
24346
|
-
|
|
24466
|
+
if (!data._federation) {
|
|
24467
|
+
const partnerName = partnerNames.get(federatedSpace);
|
|
24468
|
+
data._federation = {
|
|
24347
24469
|
origin: federatedSpace,
|
|
24348
|
-
|
|
24470
|
+
sourceLens: lens,
|
|
24471
|
+
timestamp: now,
|
|
24472
|
+
...partnerName ? { originName: partnerName } : {}
|
|
24349
24473
|
};
|
|
24350
24474
|
}
|
|
24351
24475
|
await callback(data, federatedSpace, lens);
|
|
@@ -24390,8 +24514,8 @@ async function getFederatedConfig(holosphere, spaceId, targetSpaceId, password =
|
|
|
24390
24514
|
const fedInfo = await getFederation(holosphere, spaceId, password);
|
|
24391
24515
|
if (fedInfo && fedInfo.lensConfig && fedInfo.lensConfig[targetSpaceId]) {
|
|
24392
24516
|
return {
|
|
24393
|
-
|
|
24394
|
-
|
|
24517
|
+
inbound: fedInfo.lensConfig[targetSpaceId].inbound || [],
|
|
24518
|
+
outbound: fedInfo.lensConfig[targetSpaceId].outbound || []
|
|
24395
24519
|
};
|
|
24396
24520
|
}
|
|
24397
24521
|
return null;
|
|
@@ -24414,14 +24538,20 @@ async function unfederate(holosphere, spaceId1, spaceId2, password1 = null, pass
|
|
|
24414
24538
|
if (!fedInfo1) {
|
|
24415
24539
|
console.warn(`No federation info found for ${spaceId1}. Skipping its update.`);
|
|
24416
24540
|
} else {
|
|
24417
|
-
if (!fedInfo1.
|
|
24418
|
-
if (!fedInfo1.
|
|
24419
|
-
|
|
24420
|
-
|
|
24421
|
-
fedInfo1.
|
|
24422
|
-
|
|
24541
|
+
if (!fedInfo1.federated) fedInfo1.federated = [];
|
|
24542
|
+
if (!fedInfo1.inbound) fedInfo1.inbound = [];
|
|
24543
|
+
if (!fedInfo1.outbound) fedInfo1.outbound = [];
|
|
24544
|
+
if (!fedInfo1.lensConfig) fedInfo1.lensConfig = {};
|
|
24545
|
+
if (!fedInfo1.partnerNames) fedInfo1.partnerNames = {};
|
|
24546
|
+
const beforeIn = fedInfo1.inbound.length;
|
|
24547
|
+
const beforeOut = fedInfo1.outbound.length;
|
|
24548
|
+
fedInfo1.federated = fedInfo1.federated.filter((id) => id !== spaceId2);
|
|
24549
|
+
fedInfo1.inbound = fedInfo1.inbound.filter((id) => id !== spaceId2);
|
|
24550
|
+
fedInfo1.outbound = fedInfo1.outbound.filter((id) => id !== spaceId2);
|
|
24551
|
+
delete fedInfo1.lensConfig[spaceId2];
|
|
24552
|
+
delete fedInfo1.partnerNames[spaceId2];
|
|
24423
24553
|
fedInfo1.timestamp = Date.now();
|
|
24424
|
-
console.log(`Unfederate:
|
|
24554
|
+
console.log(`Unfederate: removed ${spaceId2} from ${spaceId1}: inbound ${beforeIn} -> ${fedInfo1.inbound.length}, outbound ${beforeOut} -> ${fedInfo1.outbound.length}`);
|
|
24425
24555
|
try {
|
|
24426
24556
|
await holosphere.putGlobal("federation", fedInfo1, password1);
|
|
24427
24557
|
} catch (error) {
|
|
@@ -24436,10 +24566,19 @@ async function unfederate(holosphere, spaceId1, spaceId2, password1 = null, pass
|
|
|
24436
24566
|
} catch (error) {
|
|
24437
24567
|
console.error(`Error getting fedInfo2 for ${spaceId2} during unfederate: ${error.message}`);
|
|
24438
24568
|
}
|
|
24439
|
-
if (!fedInfo2
|
|
24440
|
-
console.warn(`No
|
|
24569
|
+
if (!fedInfo2) {
|
|
24570
|
+
console.warn(`No federation info found for ${spaceId2}. Skipping its update.`);
|
|
24441
24571
|
} else {
|
|
24442
|
-
fedInfo2.
|
|
24572
|
+
if (!fedInfo2.federated) fedInfo2.federated = [];
|
|
24573
|
+
if (!fedInfo2.inbound) fedInfo2.inbound = [];
|
|
24574
|
+
if (!fedInfo2.outbound) fedInfo2.outbound = [];
|
|
24575
|
+
if (!fedInfo2.lensConfig) fedInfo2.lensConfig = {};
|
|
24576
|
+
if (!fedInfo2.partnerNames) fedInfo2.partnerNames = {};
|
|
24577
|
+
fedInfo2.federated = fedInfo2.federated.filter((id) => id !== spaceId1);
|
|
24578
|
+
fedInfo2.inbound = fedInfo2.inbound.filter((id) => id !== spaceId1);
|
|
24579
|
+
fedInfo2.outbound = fedInfo2.outbound.filter((id) => id !== spaceId1);
|
|
24580
|
+
delete fedInfo2.lensConfig[spaceId1];
|
|
24581
|
+
delete fedInfo2.partnerNames[spaceId1];
|
|
24443
24582
|
fedInfo2.timestamp = Date.now();
|
|
24444
24583
|
try {
|
|
24445
24584
|
await holosphere.putGlobal("federation", fedInfo2, password2);
|
|
@@ -24472,19 +24611,19 @@ async function removeNotify(holosphere, spaceId1, spaceId2, password1 = null) {
|
|
|
24472
24611
|
throw new Error("removeNotify: Missing required space IDs");
|
|
24473
24612
|
}
|
|
24474
24613
|
try {
|
|
24475
|
-
|
|
24614
|
+
const fedInfo = await holosphere.getGlobal("federation", spaceId1, password1);
|
|
24476
24615
|
if (!fedInfo) {
|
|
24477
24616
|
throw new Error(`No federation info found for ${spaceId1}`);
|
|
24478
24617
|
}
|
|
24479
|
-
if (!fedInfo.
|
|
24480
|
-
if (fedInfo.
|
|
24481
|
-
|
|
24482
|
-
|
|
24483
|
-
|
|
24484
|
-
return true;
|
|
24485
|
-
} else {
|
|
24486
|
-
return false;
|
|
24618
|
+
if (!fedInfo.outbound) fedInfo.outbound = [];
|
|
24619
|
+
if (!fedInfo.outbound.includes(spaceId2)) return false;
|
|
24620
|
+
fedInfo.outbound = fedInfo.outbound.filter((id) => id !== spaceId2);
|
|
24621
|
+
if (fedInfo.lensConfig?.[spaceId2]) {
|
|
24622
|
+
fedInfo.lensConfig[spaceId2].outbound = [];
|
|
24487
24623
|
}
|
|
24624
|
+
fedInfo.timestamp = Date.now();
|
|
24625
|
+
await holosphere.putGlobal("federation", fedInfo, password1);
|
|
24626
|
+
return true;
|
|
24488
24627
|
} catch (error) {
|
|
24489
24628
|
throw error;
|
|
24490
24629
|
}
|
|
@@ -24519,10 +24658,29 @@ async function getFederated(holosphere, holon, lens, options = {}) {
|
|
|
24519
24658
|
if (includeLocal) {
|
|
24520
24659
|
spacesToQuery.push(holon);
|
|
24521
24660
|
}
|
|
24522
|
-
if (includeFederated && fedInfo && fedInfo.
|
|
24523
|
-
const federatedSpaces = maxFederatedSpaces === -1 ? fedInfo.
|
|
24661
|
+
if (includeFederated && fedInfo && fedInfo.inbound && fedInfo.inbound.length > 0) {
|
|
24662
|
+
const federatedSpaces = maxFederatedSpaces === -1 ? fedInfo.inbound : fedInfo.inbound.slice(0, maxFederatedSpaces);
|
|
24524
24663
|
spacesToQuery = spacesToQuery.concat(federatedSpaces);
|
|
24525
24664
|
}
|
|
24665
|
+
const remoteSpaces = spacesToQuery.filter((s) => s !== holon);
|
|
24666
|
+
const spaceNames = /* @__PURE__ */ new Map();
|
|
24667
|
+
await Promise.all(
|
|
24668
|
+
remoteSpaces.map(async (space) => {
|
|
24669
|
+
const name = await getHolonName(holosphere, space);
|
|
24670
|
+
spaceNames.set(space, name);
|
|
24671
|
+
})
|
|
24672
|
+
);
|
|
24673
|
+
const tagWithSource = (item, space) => {
|
|
24674
|
+
if (!item || space === holon) return item;
|
|
24675
|
+
const originName = spaceNames.get(space);
|
|
24676
|
+
const fed = {
|
|
24677
|
+
...item._federation || {},
|
|
24678
|
+
origin: space,
|
|
24679
|
+
sourceLens: lens
|
|
24680
|
+
};
|
|
24681
|
+
if (originName) fed.originName = originName;
|
|
24682
|
+
return { ...item, _federation: fed };
|
|
24683
|
+
};
|
|
24526
24684
|
for (const currentSpace of spacesToQuery) {
|
|
24527
24685
|
if (queryIds && Array.isArray(queryIds)) {
|
|
24528
24686
|
console.log(`Fetching specific IDs from ${currentSpace}: ${queryIds.join(", ")}`);
|
|
@@ -24531,7 +24689,7 @@ async function getFederated(holosphere, holon, lens, options = {}) {
|
|
|
24531
24689
|
fetchPromises.push(
|
|
24532
24690
|
holosphere.get(currentSpace, lens, itemId).then((item) => {
|
|
24533
24691
|
if (item) {
|
|
24534
|
-
fetchedItems.set(itemId, item);
|
|
24692
|
+
fetchedItems.set(itemId, tagWithSource(item, currentSpace));
|
|
24535
24693
|
}
|
|
24536
24694
|
}).catch((err) => console.warn(`Error fetching item ${itemId} from ${currentSpace}: ${err.message}`))
|
|
24537
24695
|
);
|
|
@@ -24545,7 +24703,7 @@ async function getFederated(holosphere, holon, lens, options = {}) {
|
|
|
24545
24703
|
holosphere.getAll(currentSpace, lens).then((items) => {
|
|
24546
24704
|
for (const item of items) {
|
|
24547
24705
|
if (item && item[idField] && !fetchedItems.has(item[idField])) {
|
|
24548
|
-
fetchedItems.set(item[idField], item);
|
|
24706
|
+
fetchedItems.set(item[idField], tagWithSource(item, currentSpace));
|
|
24549
24707
|
}
|
|
24550
24708
|
}
|
|
24551
24709
|
}).catch((err) => console.warn(`Error fetching all items from ${currentSpace}: ${err.message}`))
|
|
@@ -24577,24 +24735,29 @@ async function getFederated(holosphere, holon, lens, options = {}) {
|
|
|
24577
24735
|
);
|
|
24578
24736
|
console.log(`Original data found via soul path:`, JSON.stringify(originalData));
|
|
24579
24737
|
if (originalData) {
|
|
24580
|
-
|
|
24581
|
-
|
|
24582
|
-
|
|
24583
|
-
|
|
24584
|
-
|
|
24585
|
-
|
|
24586
|
-
timestamp: Date.now()
|
|
24738
|
+
const withMeta = attachHologramMeta(originalData, item.soul);
|
|
24739
|
+
if (withMeta._hologram?.sourceHolon) {
|
|
24740
|
+
let sourceHolonName = spaceNames.get(withMeta._hologram.sourceHolon);
|
|
24741
|
+
if (sourceHolonName === void 0) {
|
|
24742
|
+
sourceHolonName = await getHolonName(holosphere, withMeta._hologram.sourceHolon);
|
|
24743
|
+
spaceNames.set(withMeta._hologram.sourceHolon, sourceHolonName);
|
|
24587
24744
|
}
|
|
24588
|
-
|
|
24745
|
+
if (sourceHolonName) {
|
|
24746
|
+
withMeta._hologram = {
|
|
24747
|
+
...withMeta._hologram,
|
|
24748
|
+
sourceHolonName
|
|
24749
|
+
};
|
|
24750
|
+
}
|
|
24751
|
+
}
|
|
24752
|
+
result[i] = withMeta;
|
|
24589
24753
|
} else {
|
|
24590
24754
|
result[i] = {
|
|
24591
24755
|
id: item.id,
|
|
24592
|
-
|
|
24593
|
-
|
|
24594
|
-
resolved: false,
|
|
24756
|
+
_hologram: {
|
|
24757
|
+
isHologram: false,
|
|
24595
24758
|
soul: item.soul,
|
|
24596
24759
|
error: "Referenced data not found",
|
|
24597
|
-
|
|
24760
|
+
resolvedAt: Date.now()
|
|
24598
24761
|
}
|
|
24599
24762
|
};
|
|
24600
24763
|
}
|
|
@@ -24602,55 +24765,25 @@ async function getFederated(holosphere, holon, lens, options = {}) {
|
|
|
24602
24765
|
console.warn(`Soul doesn't match expected format: ${item.soul}`);
|
|
24603
24766
|
result[i] = {
|
|
24604
24767
|
id: item.id,
|
|
24605
|
-
|
|
24606
|
-
|
|
24607
|
-
resolved: false,
|
|
24768
|
+
_hologram: {
|
|
24769
|
+
isHologram: false,
|
|
24608
24770
|
soul: item.soul,
|
|
24609
24771
|
error: "Invalid soul format",
|
|
24610
|
-
|
|
24772
|
+
resolvedAt: Date.now()
|
|
24611
24773
|
}
|
|
24612
24774
|
};
|
|
24613
24775
|
}
|
|
24614
24776
|
} catch (refError) {
|
|
24615
24777
|
result[i] = {
|
|
24616
24778
|
id: item.id,
|
|
24617
|
-
|
|
24618
|
-
|
|
24619
|
-
resolved: false,
|
|
24779
|
+
_hologram: {
|
|
24780
|
+
isHologram: false,
|
|
24620
24781
|
soul: item.soul,
|
|
24621
24782
|
error: refError.message || "Error resolving reference",
|
|
24622
|
-
|
|
24783
|
+
resolvedAt: Date.now()
|
|
24623
24784
|
}
|
|
24624
24785
|
};
|
|
24625
24786
|
}
|
|
24626
|
-
} else if (item._federation && item._federation.isReference) {
|
|
24627
|
-
console.log(`Found legacy reference: ${item._federation.origin}/${item._federation.lens}/${item[idField]}`);
|
|
24628
|
-
try {
|
|
24629
|
-
const reference = item._federation;
|
|
24630
|
-
console.log(`Getting original data from ${reference.origin} / ${reference.lens} / ${item[idField]}`);
|
|
24631
|
-
const originalData = await holosphere.get(
|
|
24632
|
-
reference.origin,
|
|
24633
|
-
reference.lens,
|
|
24634
|
-
item[idField],
|
|
24635
|
-
null,
|
|
24636
|
-
{ resolveReferences: false }
|
|
24637
|
-
// Prevent infinite recursion
|
|
24638
|
-
);
|
|
24639
|
-
console.log(`Original data found:`, JSON.stringify(originalData));
|
|
24640
|
-
if (originalData) {
|
|
24641
|
-
result[i] = {
|
|
24642
|
-
...originalData,
|
|
24643
|
-
_federation: {
|
|
24644
|
-
...reference,
|
|
24645
|
-
resolved: true,
|
|
24646
|
-
timestamp: Date.now()
|
|
24647
|
-
}
|
|
24648
|
-
};
|
|
24649
|
-
} else {
|
|
24650
|
-
console.warn(`Could not resolve legacy reference: original data not found`);
|
|
24651
|
-
}
|
|
24652
|
-
} catch (refError) {
|
|
24653
|
-
}
|
|
24654
24787
|
}
|
|
24655
24788
|
}
|
|
24656
24789
|
}
|
|
@@ -24717,8 +24850,8 @@ async function propagate(holosphere, holon, lens, data, options = {}) {
|
|
|
24717
24850
|
};
|
|
24718
24851
|
try {
|
|
24719
24852
|
const fedInfo = await getFederation(holosphere, holon, password);
|
|
24720
|
-
if (fedInfo && fedInfo.
|
|
24721
|
-
let spaces = fedInfo.
|
|
24853
|
+
if (fedInfo && fedInfo.outbound && fedInfo.outbound.length > 0) {
|
|
24854
|
+
let spaces = fedInfo.outbound;
|
|
24722
24855
|
if (targetSpaces && Array.isArray(targetSpaces) && targetSpaces.length > 0) {
|
|
24723
24856
|
spaces = spaces.filter((space) => targetSpaces.includes(space));
|
|
24724
24857
|
}
|
|
@@ -24730,17 +24863,17 @@ async function propagate(holosphere, holon, lens, data, options = {}) {
|
|
|
24730
24863
|
result.skipped++;
|
|
24731
24864
|
return false;
|
|
24732
24865
|
}
|
|
24733
|
-
const
|
|
24734
|
-
const
|
|
24735
|
-
const shouldPropagate = shouldFederate;
|
|
24866
|
+
const outboundLenses = Array.isArray(spaceConfig.outbound) ? spaceConfig.outbound : [];
|
|
24867
|
+
const shouldPropagate = outboundLenses.includes("*") || outboundLenses.includes(lens);
|
|
24736
24868
|
if (!shouldPropagate) {
|
|
24737
|
-
result.messages.push(`Propagation of lens '${lens}' to target space ${targetSpace} skipped: lens not in '
|
|
24869
|
+
result.messages.push(`Propagation of lens '${lens}' to target space ${targetSpace} skipped: lens not in 'outbound' configuration.`);
|
|
24738
24870
|
result.skipped++;
|
|
24739
24871
|
}
|
|
24740
24872
|
return shouldPropagate;
|
|
24741
24873
|
});
|
|
24742
24874
|
if (spaces.length > 0) {
|
|
24743
24875
|
const isAlreadyHologram = holosphere.isHologram(data);
|
|
24876
|
+
const ownName = await getHolonName(holosphere, holon);
|
|
24744
24877
|
const propagatePromises = spaces.map(async (targetSpace) => {
|
|
24745
24878
|
try {
|
|
24746
24879
|
let payloadToPut;
|
|
@@ -24750,7 +24883,8 @@ async function propagate(holosphere, holon, lens, data, options = {}) {
|
|
|
24750
24883
|
sourceLens: lens,
|
|
24751
24884
|
// The lens from which this data is being propagated
|
|
24752
24885
|
propagatedAt: Date.now(),
|
|
24753
|
-
originalId: data.id
|
|
24886
|
+
originalId: data.id,
|
|
24887
|
+
...ownName ? { originName: ownName } : {}
|
|
24754
24888
|
};
|
|
24755
24889
|
if (useHolograms && !isAlreadyHologram) {
|
|
24756
24890
|
const newHologram = holosphere.createHologram(holon, lens, data);
|
|
@@ -24835,6 +24969,7 @@ async function propagate(holosphere, holon, lens, data, options = {}) {
|
|
|
24835
24969
|
if (parentHexagons.length > 0) {
|
|
24836
24970
|
result.parentPropagation.messages.push(`Found ${parentHexagons.length} parent hexagons to propagate to: ${parentHexagons.join(", ")}`);
|
|
24837
24971
|
const isAlreadyHologram = holosphere.isHologram(data);
|
|
24972
|
+
const ownNameParent = await getHolonName(holosphere, holon);
|
|
24838
24973
|
const parentPropagatePromises = parentHexagons.map(async (parentHexagon) => {
|
|
24839
24974
|
try {
|
|
24840
24975
|
let payloadToPut;
|
|
@@ -24847,8 +24982,9 @@ async function propagate(holosphere, holon, lens, data, options = {}) {
|
|
|
24847
24982
|
originalId: data.id,
|
|
24848
24983
|
propagationType: "parent",
|
|
24849
24984
|
// Indicate this is parent propagation
|
|
24850
|
-
parentLevel: holonResolution - getResolution(parentHexagon)
|
|
24985
|
+
parentLevel: holonResolution - getResolution(parentHexagon),
|
|
24851
24986
|
// How many levels up
|
|
24987
|
+
...ownNameParent ? { originName: ownNameParent } : {}
|
|
24852
24988
|
};
|
|
24853
24989
|
if (useHolograms && !isAlreadyHologram) {
|
|
24854
24990
|
const newHologram = holosphere.createHologram(holon, lens, data);
|
|
@@ -24963,60 +25099,64 @@ async function resetFederation(holosphere, spaceId, password = null, options = {
|
|
|
24963
25099
|
message: "No federation configuration found for this space"
|
|
24964
25100
|
};
|
|
24965
25101
|
}
|
|
24966
|
-
|
|
24967
|
-
result.
|
|
25102
|
+
const allPartners = fedInfo.federated || [];
|
|
25103
|
+
result.federatedCount = allPartners.length;
|
|
25104
|
+
result.inboundCount = fedInfo.inbound?.length || 0;
|
|
25105
|
+
result.outboundCount = fedInfo.outbound?.length || 0;
|
|
24968
25106
|
const emptyFedInfo = {
|
|
24969
25107
|
id: spaceId,
|
|
24970
25108
|
name: spaceName || spaceId,
|
|
24971
|
-
|
|
24972
|
-
|
|
25109
|
+
federated: [],
|
|
25110
|
+
inbound: [],
|
|
25111
|
+
outbound: [],
|
|
25112
|
+
lensConfig: {},
|
|
25113
|
+
partnerNames: {},
|
|
24973
25114
|
timestamp: Date.now()
|
|
24974
25115
|
};
|
|
24975
25116
|
await holosphere.putGlobal("federation", emptyFedInfo, password);
|
|
24976
|
-
if (notifyPartners &&
|
|
24977
|
-
const updatePromises =
|
|
25117
|
+
if (notifyPartners && allPartners.length > 0) {
|
|
25118
|
+
const updatePromises = allPartners.map(async (partnerSpace) => {
|
|
24978
25119
|
try {
|
|
24979
25120
|
const partnerFedInfo = await getFederation(holosphere, partnerSpace);
|
|
24980
|
-
if (partnerFedInfo)
|
|
24981
|
-
|
|
24982
|
-
|
|
24983
|
-
|
|
24984
|
-
);
|
|
24985
|
-
}
|
|
24986
|
-
if (partnerFedInfo.notify) {
|
|
24987
|
-
partnerFedInfo.notify = partnerFedInfo.notify.filter(
|
|
24988
|
-
(id) => id !== spaceId.toString()
|
|
24989
|
-
);
|
|
24990
|
-
}
|
|
24991
|
-
partnerFedInfo.timestamp = Date.now();
|
|
24992
|
-
await holosphere.putGlobal("federation", partnerFedInfo);
|
|
24993
|
-
result.partnersNotified++;
|
|
24994
|
-
return true;
|
|
25121
|
+
if (!partnerFedInfo) return false;
|
|
25122
|
+
const sid = spaceId.toString();
|
|
25123
|
+
if (partnerFedInfo.federated) {
|
|
25124
|
+
partnerFedInfo.federated = partnerFedInfo.federated.filter((id) => id !== sid);
|
|
24995
25125
|
}
|
|
24996
|
-
|
|
25126
|
+
if (partnerFedInfo.inbound) {
|
|
25127
|
+
partnerFedInfo.inbound = partnerFedInfo.inbound.filter((id) => id !== sid);
|
|
25128
|
+
}
|
|
25129
|
+
if (partnerFedInfo.outbound) {
|
|
25130
|
+
partnerFedInfo.outbound = partnerFedInfo.outbound.filter((id) => id !== sid);
|
|
25131
|
+
}
|
|
25132
|
+
if (partnerFedInfo.lensConfig) {
|
|
25133
|
+
delete partnerFedInfo.lensConfig[sid];
|
|
25134
|
+
}
|
|
25135
|
+
if (partnerFedInfo.partnerNames) {
|
|
25136
|
+
delete partnerFedInfo.partnerNames[sid];
|
|
25137
|
+
}
|
|
25138
|
+
partnerFedInfo.timestamp = Date.now();
|
|
25139
|
+
await holosphere.putGlobal("federation", partnerFedInfo);
|
|
25140
|
+
result.partnersNotified++;
|
|
25141
|
+
return true;
|
|
24997
25142
|
} catch (error) {
|
|
24998
|
-
result.errors.push({
|
|
24999
|
-
partner: partnerSpace,
|
|
25000
|
-
error: error.message
|
|
25001
|
-
});
|
|
25143
|
+
result.errors.push({ partner: partnerSpace, error: error.message });
|
|
25002
25144
|
return false;
|
|
25003
25145
|
}
|
|
25004
25146
|
});
|
|
25005
25147
|
await Promise.all(updatePromises);
|
|
25006
25148
|
}
|
|
25007
|
-
|
|
25008
|
-
|
|
25009
|
-
|
|
25010
|
-
|
|
25011
|
-
|
|
25012
|
-
|
|
25013
|
-
|
|
25014
|
-
|
|
25015
|
-
|
|
25016
|
-
await holosphere.putGlobal("federationMeta", meta);
|
|
25017
|
-
}
|
|
25018
|
-
} catch (error) {
|
|
25149
|
+
for (const partnerSpace of allPartners) {
|
|
25150
|
+
try {
|
|
25151
|
+
const metaId = `${spaceId}_${partnerSpace}`;
|
|
25152
|
+
const altMetaId = `${partnerSpace}_${spaceId}`;
|
|
25153
|
+
const meta = await holosphere.getGlobal("federationMeta", metaId) || await holosphere.getGlobal("federationMeta", altMetaId);
|
|
25154
|
+
if (meta) {
|
|
25155
|
+
meta.status = "inactive";
|
|
25156
|
+
meta.endedAt = Date.now();
|
|
25157
|
+
await holosphere.putGlobal("federationMeta", meta);
|
|
25019
25158
|
}
|
|
25159
|
+
} catch {
|
|
25020
25160
|
}
|
|
25021
25161
|
}
|
|
25022
25162
|
result.success = true;
|
|
@@ -25031,7 +25171,6 @@ async function resetFederation(holosphere, spaceId, password = null, options = {
|
|
|
25031
25171
|
}
|
|
25032
25172
|
|
|
25033
25173
|
// schema.js
|
|
25034
|
-
var import__ = __toESM(require__(), 1);
|
|
25035
25174
|
async function setSchema(holoInstance, lens, schema) {
|
|
25036
25175
|
if (!lens || !schema) {
|
|
25037
25176
|
throw new Error("setSchema: Missing required parameters");
|
|
@@ -25113,6 +25252,45 @@ function clearSchemaCache(holoInstance, lens = null) {
|
|
|
25113
25252
|
}
|
|
25114
25253
|
|
|
25115
25254
|
// content.js
|
|
25255
|
+
function sanitizeForStorage(value, path = "", seen = /* @__PURE__ */ new WeakSet(), warnings = []) {
|
|
25256
|
+
if (value === null) return null;
|
|
25257
|
+
const t = typeof value;
|
|
25258
|
+
if (t === "number") {
|
|
25259
|
+
if (!Number.isFinite(value)) {
|
|
25260
|
+
warnings.push(`${path || "<root>"}: ${value} (non-finite number)`);
|
|
25261
|
+
return void 0;
|
|
25262
|
+
}
|
|
25263
|
+
return value;
|
|
25264
|
+
}
|
|
25265
|
+
if (t === "string" || t === "boolean") return value;
|
|
25266
|
+
if (t === "undefined" || t === "function" || t === "symbol" || t === "bigint") {
|
|
25267
|
+
warnings.push(`${path || "<root>"}: ${t}`);
|
|
25268
|
+
return void 0;
|
|
25269
|
+
}
|
|
25270
|
+
if (t === "object") {
|
|
25271
|
+
if (seen.has(value)) {
|
|
25272
|
+
warnings.push(`${path || "<root>"}: circular reference`);
|
|
25273
|
+
return void 0;
|
|
25274
|
+
}
|
|
25275
|
+
seen.add(value);
|
|
25276
|
+
if (Array.isArray(value)) {
|
|
25277
|
+
const out2 = [];
|
|
25278
|
+
for (let i = 0; i < value.length; i++) {
|
|
25279
|
+
const cleaned = sanitizeForStorage(value[i], `${path}[${i}]`, seen, warnings);
|
|
25280
|
+
out2.push(cleaned === void 0 ? null : cleaned);
|
|
25281
|
+
}
|
|
25282
|
+
return out2;
|
|
25283
|
+
}
|
|
25284
|
+
const out = {};
|
|
25285
|
+
for (const k of Object.keys(value)) {
|
|
25286
|
+
const cleaned = sanitizeForStorage(value[k], path ? `${path}.${k}` : k, seen, warnings);
|
|
25287
|
+
if (cleaned !== void 0) out[k] = cleaned;
|
|
25288
|
+
}
|
|
25289
|
+
return out;
|
|
25290
|
+
}
|
|
25291
|
+
warnings.push(`${path || "<root>"}: unsupported type ${t}`);
|
|
25292
|
+
return void 0;
|
|
25293
|
+
}
|
|
25116
25294
|
async function put(holoInstance, holon, lens, data, password = null, options = {}) {
|
|
25117
25295
|
if (!data) {
|
|
25118
25296
|
throw new Error("put: Missing required data parameter");
|
|
@@ -25210,10 +25388,16 @@ async function put(holoInstance, holon, lens, data, password = null, options = {
|
|
|
25210
25388
|
}
|
|
25211
25389
|
return new Promise((resolve, reject) => {
|
|
25212
25390
|
try {
|
|
25213
|
-
|
|
25214
|
-
|
|
25215
|
-
|
|
25391
|
+
const sanitizeWarnings = [];
|
|
25392
|
+
let dataToStore = sanitizeForStorage(data, "", /* @__PURE__ */ new WeakSet(), sanitizeWarnings) || {};
|
|
25393
|
+
if (sanitizeWarnings.length > 0) {
|
|
25394
|
+
console.warn(
|
|
25395
|
+
`holosphere.put: sanitized ${sanitizeWarnings.length} field(s) at ${targetHolon}/${targetLens}/${targetKey} (id=${data.id}):`,
|
|
25396
|
+
sanitizeWarnings
|
|
25397
|
+
);
|
|
25216
25398
|
}
|
|
25399
|
+
if (dataToStore._meta !== void 0) delete dataToStore._meta;
|
|
25400
|
+
if (dataToStore._hologram !== void 0) delete dataToStore._hologram;
|
|
25217
25401
|
const payload = JSON.stringify(dataToStore);
|
|
25218
25402
|
const putCallback = async (ack) => {
|
|
25219
25403
|
if (ack.err) {
|
|
@@ -25503,7 +25687,8 @@ async function getAll(holoInstance, holon, lens, password = null) {
|
|
|
25503
25687
|
const output = /* @__PURE__ */ new Map();
|
|
25504
25688
|
const pendingProcessing = [];
|
|
25505
25689
|
const dataPath = password ? user.get("private").get(lens) : holoInstance.gun.get(holoInstance.appname).get(holon).get(lens);
|
|
25506
|
-
dataPath.once((
|
|
25690
|
+
const shallowOnce = () => new Promise((res) => dataPath.once((d) => res(d)));
|
|
25691
|
+
const processShallow = (data) => {
|
|
25507
25692
|
if (!data) {
|
|
25508
25693
|
resolve([]);
|
|
25509
25694
|
return;
|
|
@@ -25520,72 +25705,75 @@ async function getAll(holoInstance, holon, lens, password = null) {
|
|
|
25520
25705
|
resolve([]);
|
|
25521
25706
|
return;
|
|
25522
25707
|
}
|
|
25523
|
-
|
|
25524
|
-
|
|
25525
|
-
|
|
25526
|
-
|
|
25527
|
-
if (
|
|
25528
|
-
|
|
25529
|
-
|
|
25530
|
-
|
|
25531
|
-
|
|
25532
|
-
|
|
25533
|
-
|
|
25534
|
-
|
|
25535
|
-
|
|
25536
|
-
|
|
25537
|
-
|
|
25538
|
-
|
|
25539
|
-
|
|
25540
|
-
|
|
25541
|
-
maxDepth: 10,
|
|
25542
|
-
currentDepth: 0
|
|
25543
|
-
});
|
|
25544
|
-
if (resolved === null) {
|
|
25545
|
-
console.warn(`Broken hologram detected in getAll for key ${key}. Removing it...`);
|
|
25546
|
-
try {
|
|
25547
|
-
await holoInstance.delete(holon, lens, key, password);
|
|
25548
|
-
} catch (cleanupError) {
|
|
25549
|
-
console.error(`Failed to remove broken hologram at ${holon}/${lens}/${key}:`, cleanupError);
|
|
25550
|
-
}
|
|
25551
|
-
return;
|
|
25708
|
+
const processItem = async (itemData, key) => {
|
|
25709
|
+
if (!itemData) return;
|
|
25710
|
+
try {
|
|
25711
|
+
const parsed = await holoInstance.parse(itemData);
|
|
25712
|
+
if (!parsed || !parsed.id) return;
|
|
25713
|
+
if (holoInstance.isHologram(parsed)) {
|
|
25714
|
+
try {
|
|
25715
|
+
const resolved = await holoInstance.resolveHologram(parsed, {
|
|
25716
|
+
followHolograms: true,
|
|
25717
|
+
maxDepth: 10,
|
|
25718
|
+
currentDepth: 0
|
|
25719
|
+
});
|
|
25720
|
+
if (resolved === null) {
|
|
25721
|
+
console.warn(`Broken hologram detected in getAll for key ${key}. Removing it...`);
|
|
25722
|
+
try {
|
|
25723
|
+
await holoInstance.delete(holon, lens, key, password);
|
|
25724
|
+
} catch (cleanupError) {
|
|
25725
|
+
console.error(`Failed to remove broken hologram at ${holon}/${lens}/${key}:`, cleanupError);
|
|
25552
25726
|
}
|
|
25553
|
-
|
|
25554
|
-
|
|
25555
|
-
|
|
25556
|
-
|
|
25557
|
-
|
|
25558
|
-
|
|
25559
|
-
} else {
|
|
25727
|
+
return;
|
|
25728
|
+
}
|
|
25729
|
+
if (resolved && resolved !== parsed) {
|
|
25730
|
+
if (schema) {
|
|
25731
|
+
const valid = holoInstance.validator.validate(schema, resolved);
|
|
25732
|
+
if (valid || !holoInstance.strict) {
|
|
25560
25733
|
output.set(resolved.id, resolved);
|
|
25561
25734
|
}
|
|
25562
|
-
|
|
25735
|
+
} else {
|
|
25736
|
+
output.set(resolved.id, resolved);
|
|
25563
25737
|
}
|
|
25564
|
-
} catch (hologramError) {
|
|
25565
|
-
console.error(`Error resolving hologram for key ${key}:`, hologramError);
|
|
25566
25738
|
return;
|
|
25567
25739
|
}
|
|
25740
|
+
} catch (hologramError) {
|
|
25741
|
+
console.error(`Error resolving hologram for key ${key}:`, hologramError);
|
|
25742
|
+
return;
|
|
25568
25743
|
}
|
|
25569
|
-
|
|
25570
|
-
|
|
25571
|
-
|
|
25572
|
-
|
|
25573
|
-
}
|
|
25574
|
-
} else {
|
|
25744
|
+
}
|
|
25745
|
+
if (schema) {
|
|
25746
|
+
const valid = holoInstance.validator.validate(schema, parsed);
|
|
25747
|
+
if (valid || !holoInstance.strict) {
|
|
25575
25748
|
output.set(parsed.id, parsed);
|
|
25576
25749
|
}
|
|
25577
|
-
}
|
|
25578
|
-
|
|
25750
|
+
} else {
|
|
25751
|
+
output.set(parsed.id, parsed);
|
|
25579
25752
|
}
|
|
25580
|
-
}
|
|
25581
|
-
|
|
25582
|
-
receivedCount++;
|
|
25583
|
-
if (receivedCount >= expectedCount) {
|
|
25584
|
-
await Promise.all(pendingProcessing);
|
|
25585
|
-
resolve(Array.from(output.values()));
|
|
25753
|
+
} catch (error) {
|
|
25754
|
+
console.error("Error processing data:", error);
|
|
25586
25755
|
}
|
|
25587
|
-
}
|
|
25588
|
-
|
|
25756
|
+
};
|
|
25757
|
+
Promise.all(keys.map((key) => {
|
|
25758
|
+
const inline = data[key];
|
|
25759
|
+
if (typeof inline !== "object" || inline === null) {
|
|
25760
|
+
return processItem(inline, key);
|
|
25761
|
+
}
|
|
25762
|
+
return new Promise((resolveItem) => {
|
|
25763
|
+
dataPath.get(key).once((itemData) => {
|
|
25764
|
+
processItem(itemData, key).then(resolveItem, resolveItem);
|
|
25765
|
+
});
|
|
25766
|
+
});
|
|
25767
|
+
})).then(() => resolve(Array.from(output.values())));
|
|
25768
|
+
};
|
|
25769
|
+
(async () => {
|
|
25770
|
+
let data = await shallowOnce();
|
|
25771
|
+
if (!data) {
|
|
25772
|
+
await new Promise((r) => setTimeout(r, 1500));
|
|
25773
|
+
data = await shallowOnce();
|
|
25774
|
+
}
|
|
25775
|
+
processShallow(data);
|
|
25776
|
+
})();
|
|
25589
25777
|
});
|
|
25590
25778
|
} catch (error) {
|
|
25591
25779
|
console.error("Error in getAll:", error);
|
|
@@ -26064,6 +26252,9 @@ async function putGlobal(holoInstance, tableName, data, password = null) {
|
|
|
26064
26252
|
if (dataToStore._meta !== void 0) {
|
|
26065
26253
|
delete dataToStore._meta;
|
|
26066
26254
|
}
|
|
26255
|
+
if (dataToStore._hologram !== void 0) {
|
|
26256
|
+
delete dataToStore._hologram;
|
|
26257
|
+
}
|
|
26067
26258
|
const payload = JSON.stringify(dataToStore);
|
|
26068
26259
|
const isHologram2 = holoInstance.isHologram(dataToStore);
|
|
26069
26260
|
const dataPath = password ? user.get("private").get(tableName) : holoInstance.gun.get(holoInstance.appname).get(tableName);
|
|
@@ -26264,7 +26455,8 @@ async function getAllGlobal(holoInstance, tableName, password = null) {
|
|
|
26264
26455
|
const output = [];
|
|
26265
26456
|
const pendingProcessing = [];
|
|
26266
26457
|
const dataPath = password ? user.get("private").get(tableName) : holoInstance.gun.get(holoInstance.appname).get(tableName);
|
|
26267
|
-
dataPath.once((
|
|
26458
|
+
const shallowOnce = () => new Promise((res) => dataPath.once((d) => res(d)));
|
|
26459
|
+
const processShallow = (data) => {
|
|
26268
26460
|
if (!data) {
|
|
26269
26461
|
resolve([]);
|
|
26270
26462
|
return;
|
|
@@ -26281,52 +26473,55 @@ async function getAllGlobal(holoInstance, tableName, password = null) {
|
|
|
26281
26473
|
resolve([]);
|
|
26282
26474
|
return;
|
|
26283
26475
|
}
|
|
26284
|
-
|
|
26285
|
-
|
|
26286
|
-
|
|
26287
|
-
|
|
26288
|
-
if (
|
|
26289
|
-
|
|
26290
|
-
|
|
26291
|
-
|
|
26292
|
-
|
|
26293
|
-
|
|
26294
|
-
|
|
26295
|
-
|
|
26296
|
-
|
|
26297
|
-
|
|
26298
|
-
if (holoInstance.isHologram(parsed)) {
|
|
26299
|
-
const resolved = await holoInstance.resolveHologram(parsed, {
|
|
26300
|
-
followHolograms: true
|
|
26301
|
-
});
|
|
26302
|
-
if (resolved === null) {
|
|
26303
|
-
try {
|
|
26304
|
-
await holoInstance.deleteGlobal(tableName, key, password);
|
|
26305
|
-
} catch (deleteError) {
|
|
26306
|
-
console.error(`Failed to delete invalid global hologram at ${tableName}/${key}:`, deleteError);
|
|
26307
|
-
}
|
|
26308
|
-
return;
|
|
26309
|
-
}
|
|
26310
|
-
if (resolved !== parsed) {
|
|
26311
|
-
output.push(resolved);
|
|
26312
|
-
} else {
|
|
26313
|
-
output.push(parsed);
|
|
26476
|
+
const processItem = async (itemData, key) => {
|
|
26477
|
+
if (!itemData) return;
|
|
26478
|
+
try {
|
|
26479
|
+
const parsed = await holoInstance.parse(itemData);
|
|
26480
|
+
if (!parsed) return;
|
|
26481
|
+
if (holoInstance.isHologram(parsed)) {
|
|
26482
|
+
const resolved = await holoInstance.resolveHologram(parsed, {
|
|
26483
|
+
followHolograms: true
|
|
26484
|
+
});
|
|
26485
|
+
if (resolved === null) {
|
|
26486
|
+
try {
|
|
26487
|
+
await holoInstance.deleteGlobal(tableName, key, password);
|
|
26488
|
+
} catch (deleteError) {
|
|
26489
|
+
console.error(`Failed to delete invalid global hologram at ${tableName}/${key}:`, deleteError);
|
|
26314
26490
|
}
|
|
26491
|
+
return;
|
|
26492
|
+
}
|
|
26493
|
+
if (resolved !== parsed) {
|
|
26494
|
+
output.push(resolved);
|
|
26315
26495
|
} else {
|
|
26316
26496
|
output.push(parsed);
|
|
26317
26497
|
}
|
|
26318
|
-
}
|
|
26319
|
-
|
|
26498
|
+
} else {
|
|
26499
|
+
output.push(parsed);
|
|
26320
26500
|
}
|
|
26321
|
-
}
|
|
26322
|
-
|
|
26323
|
-
receivedCount++;
|
|
26324
|
-
if (receivedCount >= expectedCount) {
|
|
26325
|
-
await Promise.all(pendingProcessing);
|
|
26326
|
-
resolve(output);
|
|
26501
|
+
} catch (error) {
|
|
26502
|
+
console.error("Error parsing data:", error);
|
|
26327
26503
|
}
|
|
26328
|
-
}
|
|
26329
|
-
|
|
26504
|
+
};
|
|
26505
|
+
Promise.all(keys.map((key) => {
|
|
26506
|
+
const inline = data[key];
|
|
26507
|
+
if (typeof inline !== "object" || inline === null) {
|
|
26508
|
+
return processItem(inline, key);
|
|
26509
|
+
}
|
|
26510
|
+
return new Promise((resolveItem) => {
|
|
26511
|
+
dataPath.get(key).once((itemData) => {
|
|
26512
|
+
processItem(itemData, key).then(resolveItem, resolveItem);
|
|
26513
|
+
});
|
|
26514
|
+
});
|
|
26515
|
+
})).then(() => resolve(output));
|
|
26516
|
+
};
|
|
26517
|
+
(async () => {
|
|
26518
|
+
let data = await shallowOnce();
|
|
26519
|
+
if (!data) {
|
|
26520
|
+
await new Promise((r) => setTimeout(r, 1500));
|
|
26521
|
+
data = await shallowOnce();
|
|
26522
|
+
}
|
|
26523
|
+
processShallow(data);
|
|
26524
|
+
})();
|
|
26330
26525
|
});
|
|
26331
26526
|
} catch (error) {
|
|
26332
26527
|
console.error("Error in getAllGlobal:", error);
|
|
@@ -26616,116 +26811,6 @@ async function subscribeGlobal(holoInstance, tableName, key, callback, options =
|
|
|
26616
26811
|
};
|
|
26617
26812
|
}
|
|
26618
26813
|
|
|
26619
|
-
// hologram.js
|
|
26620
|
-
function createHologram(holoInstance, holon, lens, data) {
|
|
26621
|
-
if (isHologram(data)) {
|
|
26622
|
-
return {
|
|
26623
|
-
id: data.id,
|
|
26624
|
-
soul: data.soul
|
|
26625
|
-
};
|
|
26626
|
-
}
|
|
26627
|
-
if (!holon || !lens || !data || !data.id) {
|
|
26628
|
-
throw new Error("createHologram: Missing required parameters for non-hologram data");
|
|
26629
|
-
}
|
|
26630
|
-
const soul = `${holoInstance.appname}/${holon}/${lens}/${data.id}`;
|
|
26631
|
-
return {
|
|
26632
|
-
id: data.id,
|
|
26633
|
-
soul
|
|
26634
|
-
};
|
|
26635
|
-
}
|
|
26636
|
-
function parseSoulPath(soul) {
|
|
26637
|
-
if (typeof soul !== "string") return null;
|
|
26638
|
-
const parts = soul.split("/");
|
|
26639
|
-
if (parts.length < 4) return null;
|
|
26640
|
-
const key = parts.slice(3).join("/");
|
|
26641
|
-
return {
|
|
26642
|
-
appname: parts[0],
|
|
26643
|
-
holon: parts[1],
|
|
26644
|
-
lens: parts[2],
|
|
26645
|
-
key
|
|
26646
|
-
};
|
|
26647
|
-
}
|
|
26648
|
-
function isHologram(data) {
|
|
26649
|
-
if (!data || typeof data !== "object") {
|
|
26650
|
-
return false;
|
|
26651
|
-
}
|
|
26652
|
-
if (data.id && typeof data.soul === "string" && data.soul.length > 0) {
|
|
26653
|
-
if (data.soul.includes("/")) {
|
|
26654
|
-
return true;
|
|
26655
|
-
}
|
|
26656
|
-
}
|
|
26657
|
-
return false;
|
|
26658
|
-
}
|
|
26659
|
-
async function resolveHologram(holoInstance, hologram, options = {}) {
|
|
26660
|
-
if (!isHologram(hologram)) {
|
|
26661
|
-
return hologram;
|
|
26662
|
-
}
|
|
26663
|
-
const {
|
|
26664
|
-
followHolograms = true,
|
|
26665
|
-
visited = /* @__PURE__ */ new Set(),
|
|
26666
|
-
maxDepth = 10,
|
|
26667
|
-
currentDepth = 0
|
|
26668
|
-
} = options;
|
|
26669
|
-
if (currentDepth >= maxDepth) {
|
|
26670
|
-
console.warn(`!!! Maximum resolution depth (${maxDepth}) reached for soul: ${hologram.soul}. Stopping resolution.`);
|
|
26671
|
-
return null;
|
|
26672
|
-
}
|
|
26673
|
-
if (hologram.soul && visited.has(hologram.soul)) {
|
|
26674
|
-
console.warn(`!!! CIRCULAR hologram detected for soul: ${hologram.soul}. Breaking loop.`);
|
|
26675
|
-
return null;
|
|
26676
|
-
}
|
|
26677
|
-
try {
|
|
26678
|
-
if (hologram.soul) {
|
|
26679
|
-
const soulInfo = parseSoulPath(hologram.soul);
|
|
26680
|
-
if (!soulInfo) {
|
|
26681
|
-
console.warn(`Invalid soul format: ${hologram.soul}`);
|
|
26682
|
-
return null;
|
|
26683
|
-
}
|
|
26684
|
-
const nextVisited = new Set(visited);
|
|
26685
|
-
nextVisited.add(hologram.soul);
|
|
26686
|
-
const originalData = await holoInstance.get(
|
|
26687
|
-
soulInfo.holon,
|
|
26688
|
-
soulInfo.lens,
|
|
26689
|
-
soulInfo.key,
|
|
26690
|
-
null,
|
|
26691
|
-
{
|
|
26692
|
-
resolveHolograms: followHolograms,
|
|
26693
|
-
visited: nextVisited,
|
|
26694
|
-
maxDepth,
|
|
26695
|
-
currentDepth: currentDepth + 1
|
|
26696
|
-
}
|
|
26697
|
-
);
|
|
26698
|
-
if (originalData && !originalData._invalidHologram) {
|
|
26699
|
-
return {
|
|
26700
|
-
...originalData,
|
|
26701
|
-
_meta: {
|
|
26702
|
-
...originalData._meta || {},
|
|
26703
|
-
// Preserve original _meta
|
|
26704
|
-
resolvedFromHologram: true,
|
|
26705
|
-
// This is now the primary indicator
|
|
26706
|
-
hologramSoul: hologram.soul,
|
|
26707
|
-
// Clarified meta field
|
|
26708
|
-
resolutionDepth: currentDepth
|
|
26709
|
-
}
|
|
26710
|
-
};
|
|
26711
|
-
} else {
|
|
26712
|
-
console.warn(`!!! Original data NOT FOUND for soul: ${hologram.soul}. Removing broken hologram.`);
|
|
26713
|
-
return null;
|
|
26714
|
-
}
|
|
26715
|
-
} else {
|
|
26716
|
-
console.warn("!!! resolveHologram called with object missing soul:", hologram);
|
|
26717
|
-
return null;
|
|
26718
|
-
}
|
|
26719
|
-
} catch (error) {
|
|
26720
|
-
if (error.message?.startsWith("CIRCULAR_REFERENCE")) {
|
|
26721
|
-
console.warn(`!!! Circular reference detected during hologram resolution: ${error.message}`);
|
|
26722
|
-
return null;
|
|
26723
|
-
}
|
|
26724
|
-
console.error(`!!! Error resolving hologram: ${error.message}`, error);
|
|
26725
|
-
return null;
|
|
26726
|
-
}
|
|
26727
|
-
}
|
|
26728
|
-
|
|
26729
26814
|
// compute.js
|
|
26730
26815
|
async function computeHierarchy(holoInstance, holon, lens, options, maxLevels = 15, password = null) {
|
|
26731
26816
|
let currentHolon = holon;
|
|
@@ -30199,7 +30284,7 @@ var HoloSphere = class {
|
|
|
30199
30284
|
this._privateKey = null;
|
|
30200
30285
|
}
|
|
30201
30286
|
console.log("HoloSphere v" + HOLOSPHERE_VERSION);
|
|
30202
|
-
this.validator = new
|
|
30287
|
+
this.validator = new import__.default({
|
|
30203
30288
|
allErrors: true,
|
|
30204
30289
|
strict: false,
|
|
30205
30290
|
validateSchema: true
|
|
@@ -30351,6 +30436,9 @@ var HoloSphere = class {
|
|
|
30351
30436
|
async resolveHologram(hologram, options = {}) {
|
|
30352
30437
|
return resolveHologram(this, hologram, options);
|
|
30353
30438
|
}
|
|
30439
|
+
attachHologramMeta(originalData, hologramSoul) {
|
|
30440
|
+
return attachHologramMeta(originalData, hologramSoul);
|
|
30441
|
+
}
|
|
30354
30442
|
// ================================ COMPUTE FUNCTIONS ================================
|
|
30355
30443
|
async computeHierarchy(holon, lens, options, maxLevels = 15, password = null) {
|
|
30356
30444
|
return computeHierarchy(this, holon, lens, options, maxLevels, password);
|
|
@@ -30393,41 +30481,37 @@ var HoloSphere = class {
|
|
|
30393
30481
|
return federate(this, holonId1, holonId2, password1, password2, bidirectional, lensConfig);
|
|
30394
30482
|
}
|
|
30395
30483
|
/**
|
|
30396
|
-
*
|
|
30397
|
-
* Maps v2 options to v1 federate() call.
|
|
30484
|
+
* Convenience wrapper around federate() for the common bidirectional case.
|
|
30398
30485
|
* @param {string} sourceHolon - Source holon ID
|
|
30399
30486
|
* @param {string} targetHolon - Target holon ID
|
|
30400
30487
|
* @param {object} [options] - Federation options
|
|
30401
|
-
* @param {object} [options.lensConfig] - Lens
|
|
30402
|
-
* @param {string} [options.
|
|
30403
|
-
* @param {
|
|
30488
|
+
* @param {object} [options.lensConfig] - Lens config from sourceHolon's perspective
|
|
30489
|
+
* @param {string[]} [options.lensConfig.inbound] - Lenses sourceHolon receives from targetHolon
|
|
30490
|
+
* @param {string[]} [options.lensConfig.outbound] - Lenses sourceHolon sends to targetHolon
|
|
30491
|
+
* @param {string} [options.partnerName] - Display name for the partner
|
|
30404
30492
|
* @returns {Promise<boolean>}
|
|
30405
30493
|
*/
|
|
30406
30494
|
async federateHolon(sourceHolon, targetHolon, options = {}) {
|
|
30407
30495
|
const lensConfig = options.lensConfig || {};
|
|
30408
|
-
const
|
|
30409
|
-
|
|
30496
|
+
const inbound = Array.isArray(lensConfig.inbound) ? lensConfig.inbound : [];
|
|
30497
|
+
const outbound = Array.isArray(lensConfig.outbound) ? lensConfig.outbound : [];
|
|
30498
|
+
const ok = await federate(this, sourceHolon, targetHolon, null, null, true, {
|
|
30499
|
+
inbound,
|
|
30500
|
+
outbound
|
|
30501
|
+
});
|
|
30502
|
+
if (ok && options.partnerName) {
|
|
30410
30503
|
try {
|
|
30411
|
-
const fedInfo = await this.getFederation(sourceHolon)
|
|
30412
|
-
|
|
30413
|
-
|
|
30414
|
-
|
|
30415
|
-
|
|
30416
|
-
|
|
30417
|
-
partnerNames: {},
|
|
30418
|
-
timestamp: Date.now()
|
|
30419
|
-
};
|
|
30420
|
-
if (!fedInfo.partnerNames) fedInfo.partnerNames = {};
|
|
30421
|
-
fedInfo.partnerNames[targetHolon] = options.partnerName;
|
|
30422
|
-
await this.putGlobal("federation", fedInfo);
|
|
30504
|
+
const fedInfo = await this.getFederation(sourceHolon);
|
|
30505
|
+
if (fedInfo) {
|
|
30506
|
+
if (!fedInfo.partnerNames) fedInfo.partnerNames = {};
|
|
30507
|
+
fedInfo.partnerNames[targetHolon] = options.partnerName;
|
|
30508
|
+
await this.putGlobal("federation", fedInfo);
|
|
30509
|
+
}
|
|
30423
30510
|
} catch (e) {
|
|
30424
30511
|
console.warn("Failed to store partner name:", e.message);
|
|
30425
30512
|
}
|
|
30426
30513
|
}
|
|
30427
|
-
return
|
|
30428
|
-
federate: lenses,
|
|
30429
|
-
notify: lenses
|
|
30430
|
-
});
|
|
30514
|
+
return ok;
|
|
30431
30515
|
}
|
|
30432
30516
|
/**
|
|
30433
30517
|
* v2-compatible federation removal.
|