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/holosphere.d.ts CHANGED
@@ -33,15 +33,56 @@ interface Hologram {
33
33
  [key: string]: any;
34
34
  }
35
35
 
36
+ /**
37
+ * Canonical envelope attached to data resolved from a hologram reference.
38
+ *
39
+ * Single source of truth for resolved-hologram metadata. Every read path that
40
+ * returns data resolved from a hologram (get, getAll, subscribe, getFederated,
41
+ * getGlobal, getAllGlobal) attaches this field via `attachHologramMeta`.
42
+ *
43
+ * On success: `isHologram === true` and source* fields point at the origin.
44
+ * On failure: `isHologram === false` and `error` describes why resolution failed.
45
+ */
46
+ interface ResolvedHologramMeta {
47
+ isHologram: boolean;
48
+ soul: string;
49
+ sourceHolon?: string | null;
50
+ sourceLens?: string | null;
51
+ sourceKey?: string | null;
52
+ resolvedAt: number;
53
+ error?: string;
54
+ }
55
+
56
+ interface ResolvedHologramData {
57
+ _hologram: ResolvedHologramMeta;
58
+ [key: string]: any;
59
+ }
60
+
61
+ /**
62
+ * Per-partner directional lens config. Directions are from the holding
63
+ * space's perspective: `inbound` lenses are received from the partner,
64
+ * `outbound` lenses are sent to the partner.
65
+ */
66
+ interface FederationLensConfig {
67
+ inbound: string[];
68
+ outbound: string[];
69
+ timestamp: number;
70
+ }
71
+
36
72
  interface FederationInfo {
37
73
  id: string;
38
74
  name: string;
39
- federation: string[];
75
+ /** Canonical list of all federation partners (any direction, including no lens flow yet). */
40
76
  federated: string[];
41
- notify: string[];
42
- timestamp: number;
43
- lensConfig: Record<string, any>;
77
+ /** Partners we receive data FROM (subset of `federated` with non-empty inbound lenses). */
78
+ inbound: string[];
79
+ /** Partners we send data TO (subset of `federated` with non-empty outbound lenses). */
80
+ outbound: string[];
81
+ /** Per-partner directional lens config. */
82
+ lensConfig: Record<string, FederationLensConfig>;
83
+ /** Optional display names for partners. */
44
84
  partnerNames: Record<string, string>;
85
+ timestamp: number;
45
86
  }
46
87
 
47
88
  interface GetFederatedOptions {
@@ -153,7 +194,8 @@ declare class HoloSphere {
153
194
  createHologram(holon: string, lens: string, data: { id: string, [key: string]: any }): Hologram;
154
195
  isHologram(data: any): data is Hologram;
155
196
  parseSoulPath(soul: string): { appname: string, holon: string, lens: string, key: string } | null;
156
- resolveHologram(hologram: Hologram, options?: ResolveHologramOptions): Promise<object | null>;
197
+ resolveHologram(hologram: Hologram, options?: ResolveHologramOptions): Promise<ResolvedHologramData | null>;
198
+ attachHologramMeta<T extends object>(originalData: T, hologramSoul: string): T & ResolvedHologramData;
157
199
 
158
200
  // Compute
159
201
  computeHierarchy(holon: string, lens: string, options: object, maxLevels?: number, password?: string | null): Promise<Array<any>>;
@@ -172,16 +214,16 @@ declare class HoloSphere {
172
214
  subscribe(holon: string, lens: string, callback: (data: any, key?: string) => void): Promise<{ unsubscribe: () => void }>;
173
215
 
174
216
  // Federation - v1 style
175
- federate(holonId1: string, holonId2: string, password1?: string | null, password2?: string | null, bidirectional?: boolean, lensConfig?: { federate?: string[], notify?: string[] }): Promise<boolean>;
217
+ federate(holonId1: string, holonId2: string, password1?: string | null, password2?: string | null, bidirectional?: boolean, lensConfig?: { inbound?: string[], outbound?: string[] }): Promise<boolean>;
176
218
  unfederate(holonId1: string, holonId2: string, password1?: string | null, password2?: string | null): Promise<boolean>;
177
219
 
178
220
  // Federation - v2 style
179
- federateHolon(sourceHolon: string, targetHolon: string, options?: { lensConfig?: any; partnerName?: string; skipPropagation?: boolean }): Promise<boolean>;
221
+ federateHolon(sourceHolon: string, targetHolon: string, options?: { lensConfig?: { inbound?: string[]; outbound?: string[] }; partnerName?: string }): Promise<boolean>;
180
222
  unfederateHolon(sourceHolon: string, targetHolon: string): Promise<boolean>;
181
223
 
182
224
  subscribeFederation(holonId: string, password: string | null, callback: (data: any, federatedSpace?: string, lens?: string) => void, options?: { lenses?: string[], throttle?: number }): Promise<{ unsubscribe: () => void, getSubscriptionCount: () => number }>;
183
225
  getFederation(holonId: string, password?: string | null): Promise<FederationInfo | null>;
184
- getFederatedConfig(holonId: string, targetHolonId: string, password?: string | null): Promise<{ federate: string[], notify: string[] } | null>;
226
+ getFederatedConfig(holonId: string, targetHolonId: string, password?: string | null): Promise<{ inbound: string[], outbound: string[] } | null>;
185
227
  removeNotify(holonId1: string, holonId2: string, password1?: string | null): Promise<boolean>;
186
228
  getFederated(holon: string, lens: string, options?: GetFederatedOptions): Promise<Array<any>>;
187
229
  federateMessage(originalChatId: string, messageId: string, federatedChatId: string, federatedMessageId: string, type?: string): Promise<void>;
package/holosphere.js CHANGED
@@ -294,6 +294,10 @@ class HoloSphere {
294
294
  return HologramOps.resolveHologram(this, hologram, options);
295
295
  }
296
296
 
297
+ attachHologramMeta(originalData, hologramSoul) {
298
+ return HologramOps.attachHologramMeta(originalData, hologramSoul);
299
+ }
300
+
297
301
  // ================================ COMPUTE FUNCTIONS ================================
298
302
 
299
303
  async computeHierarchy(holon, lens, options, maxLevels = 15, password = null) {
@@ -351,39 +355,40 @@ class HoloSphere {
351
355
  }
352
356
 
353
357
  /**
354
- * v2-compatible federation creation.
355
- * Maps v2 options to v1 federate() call.
358
+ * Convenience wrapper around federate() for the common bidirectional case.
356
359
  * @param {string} sourceHolon - Source holon ID
357
360
  * @param {string} targetHolon - Target holon ID
358
361
  * @param {object} [options] - Federation options
359
- * @param {object} [options.lensConfig] - Lens configuration
360
- * @param {string} [options.partnerName] - Name of the partner holon
361
- * @param {boolean} [options.skipPropagation] - Skip data propagation
362
+ * @param {object} [options.lensConfig] - Lens config from sourceHolon's perspective
363
+ * @param {string[]} [options.lensConfig.inbound] - Lenses sourceHolon receives from targetHolon
364
+ * @param {string[]} [options.lensConfig.outbound] - Lenses sourceHolon sends to targetHolon
365
+ * @param {string} [options.partnerName] - Display name for the partner
362
366
  * @returns {Promise<boolean>}
363
367
  */
364
368
  async federateHolon(sourceHolon, targetHolon, options = {}) {
365
369
  const lensConfig = options.lensConfig || {};
366
- const lenses = lensConfig.lenses || lensConfig.outbound || lensConfig.federate || [];
370
+ const inbound = Array.isArray(lensConfig.inbound) ? lensConfig.inbound : [];
371
+ const outbound = Array.isArray(lensConfig.outbound) ? lensConfig.outbound : [];
372
+
373
+ const ok = await Federation.federate(this, sourceHolon, targetHolon, null, null, true, {
374
+ inbound,
375
+ outbound
376
+ });
367
377
 
368
- // Store partner name if provided
369
- if (options.partnerName) {
378
+ if (ok && options.partnerName) {
370
379
  try {
371
- const fedInfo = await this.getFederation(sourceHolon) || {
372
- id: sourceHolon, name: sourceHolon,
373
- federation: [], notify: [], lensConfig: {}, partnerNames: {}, timestamp: Date.now()
374
- };
375
- if (!fedInfo.partnerNames) fedInfo.partnerNames = {};
376
- fedInfo.partnerNames[targetHolon] = options.partnerName;
377
- await this.putGlobal('federation', fedInfo);
380
+ const fedInfo = await this.getFederation(sourceHolon);
381
+ if (fedInfo) {
382
+ if (!fedInfo.partnerNames) fedInfo.partnerNames = {};
383
+ fedInfo.partnerNames[targetHolon] = options.partnerName;
384
+ await this.putGlobal('federation', fedInfo);
385
+ }
378
386
  } catch (e) {
379
387
  console.warn('Failed to store partner name:', e.message);
380
388
  }
381
389
  }
382
390
 
383
- return Federation.federate(this, sourceHolon, targetHolon, null, null, true, {
384
- federate: lenses,
385
- notify: lenses
386
- });
391
+ return ok;
387
392
  }
388
393
 
389
394
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "holosphere",
3
- "version": "1.3.0-alpha0",
3
+ "version": "1.3.0-alpha4",
4
4
  "description": "Holonic Geospatial Communication Infrastructure",
5
5
  "main": "holosphere.js",
6
6
  "module": "holosphere.js",