holosphere 2.0.0-alpha17 → 2.0.0-alpha19

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.
Files changed (39) hide show
  1. package/dist/{2019-C9IgM3mu.cjs → 2019-CAYA1q1p.cjs} +2 -2
  2. package/dist/{2019-C9IgM3mu.cjs.map → 2019-CAYA1q1p.cjs.map} +1 -1
  3. package/dist/{2019-CyFQLuqg.js → 2019-Cc18leNN.js} +2 -2
  4. package/dist/{2019-CyFQLuqg.js.map → 2019-Cc18leNN.js.map} +1 -1
  5. package/dist/{browser-CZ1l8nhY.cjs → browser-DAFvFs8I.cjs} +2 -2
  6. package/dist/{browser-CZ1l8nhY.cjs.map → browser-DAFvFs8I.cjs.map} +1 -1
  7. package/dist/{browser-BIvmkBi9.js → browser-yWnjyL8K.js} +2 -2
  8. package/dist/{browser-BIvmkBi9.js.map → browser-yWnjyL8K.js.map} +1 -1
  9. package/dist/cjs/holosphere.cjs +1 -1
  10. package/dist/esm/holosphere.js +1 -1
  11. package/dist/{index-HW9kbrzC.js → index-Bgi_csBR.js} +2 -2
  12. package/dist/{index-HW9kbrzC.js.map → index-Bgi_csBR.js.map} +1 -1
  13. package/dist/{index-B7ERi4ng.js → index-CHfVBEUH.js} +132 -101
  14. package/dist/index-CHfVBEUH.js.map +1 -0
  15. package/dist/{index-Cc-_uNpt.cjs → index-CPvYlZtl.cjs} +2 -2
  16. package/dist/{index-Cc-_uNpt.cjs.map → index-CPvYlZtl.cjs.map} +1 -1
  17. package/dist/{index-DusXavIT.js → index-CReYsOty.js} +2 -2
  18. package/dist/{index-DusXavIT.js.map → index-CReYsOty.js.map} +1 -1
  19. package/dist/index-Dgx5DQG_.cjs +29 -0
  20. package/dist/index-Dgx5DQG_.cjs.map +1 -0
  21. package/dist/{index-VrRkpshF.cjs → index-bnw0PiyT.cjs} +2 -2
  22. package/dist/{index-VrRkpshF.cjs.map → index-bnw0PiyT.cjs.map} +1 -1
  23. package/dist/{indexeddb-storage-CVz4Q3lo.cjs → indexeddb-storage-CyOZAiHV.cjs} +2 -2
  24. package/dist/{indexeddb-storage-CVz4Q3lo.cjs.map → indexeddb-storage-CyOZAiHV.cjs.map} +1 -1
  25. package/dist/{indexeddb-storage-yEswGGMG.js → indexeddb-storage-Ko4sjZtM.js} +2 -2
  26. package/dist/{indexeddb-storage-yEswGGMG.js.map → indexeddb-storage-Ko4sjZtM.js.map} +1 -1
  27. package/dist/{memory-storage-CSB5_IfU.js → memory-storage-BTfQQ9Ig.js} +2 -2
  28. package/dist/{memory-storage-CSB5_IfU.js.map → memory-storage-BTfQQ9Ig.js.map} +1 -1
  29. package/dist/{memory-storage-Q8mEQ6Ix.cjs → memory-storage-C6YV3dsT.cjs} +2 -2
  30. package/dist/{memory-storage-Q8mEQ6Ix.cjs.map → memory-storage-C6YV3dsT.cjs.map} +1 -1
  31. package/package.json +1 -1
  32. package/src/federation/registry.js +70 -0
  33. package/src/index.js +80 -90
  34. package/src/storage/nostr-async.js +12 -8
  35. package/src/storage/nostr-client.js +5 -2
  36. package/src/subscriptions/manager.js +13 -4
  37. package/dist/index-B7ERi4ng.js.map +0 -1
  38. package/dist/index-DXFsE8r6.cjs +0 -29
  39. package/dist/index-DXFsE8r6.cjs.map +0 -1
@@ -18011,12 +18011,12 @@ async function createPersistentStorage(namespace, options = {}) {
18011
18011
  const isBrowser = typeof window !== "undefined" && typeof window.indexedDB !== "undefined";
18012
18012
  typeof process !== "undefined" && process.versions && void 0;
18013
18013
  if (isBrowser) {
18014
- const { IndexedDBStorage } = await import("./indexeddb-storage-yEswGGMG.js");
18014
+ const { IndexedDBStorage } = await import("./indexeddb-storage-Ko4sjZtM.js");
18015
18015
  const storage = new IndexedDBStorage();
18016
18016
  await storage.init(namespace);
18017
18017
  return storage;
18018
18018
  } else {
18019
- const { MemoryStorage } = await import("./memory-storage-CSB5_IfU.js");
18019
+ const { MemoryStorage } = await import("./memory-storage-BTfQQ9Ig.js");
18020
18020
  const storage = new MemoryStorage();
18021
18021
  await storage.init(namespace);
18022
18022
  return storage;
@@ -18029,7 +18029,7 @@ async function loadNDKCacheAdapter() {
18029
18029
  ndkCacheAdapterLoaded = true;
18030
18030
  if (typeof window !== "undefined" && typeof indexedDB !== "undefined") {
18031
18031
  try {
18032
- const module2 = await import("./index-DusXavIT.js");
18032
+ const module2 = await import("./index-CReYsOty.js");
18033
18033
  NDKCacheAdapterDexie = module2.default || module2.NDKCacheAdapterDexie;
18034
18034
  } catch (e) {
18035
18035
  console.debug("[nostr] NDK cache adapter not available, using LRU cache");
@@ -18306,7 +18306,9 @@ class NostrClient {
18306
18306
  this.persistentStorage = await createPersistentStorage(namespace, {
18307
18307
  dataDir: this.config.dataDir
18308
18308
  });
18309
- await this._loadFromPersistentStorage();
18309
+ this._loadFromPersistentStorage().catch((err) => {
18310
+ console.warn("Background persistent storage load failed:", err);
18311
+ });
18310
18312
  this.outboxQueue = new OutboxQueue(this.persistentStorage, {
18311
18313
  maxRetries: this.config.maxRetries || 5,
18312
18314
  baseDelay: this.config.retryBaseDelay || 1e3,
@@ -21015,7 +21017,7 @@ class GunSchemaValidator {
21015
21017
  return true;
21016
21018
  }
21017
21019
  try {
21018
- const AjvModule = await import("./2019-CyFQLuqg.js").then((n2) => n2._);
21020
+ const AjvModule = await import("./2019-Cc18leNN.js").then((n2) => n2._);
21019
21021
  this.Ajv = AjvModule.default || AjvModule;
21020
21022
  this.validator = new this.Ajv({
21021
21023
  allErrors: true,
@@ -21236,7 +21238,7 @@ class GunDBBackend extends StorageBackend {
21236
21238
  let Gun;
21237
21239
  try {
21238
21240
  console.log("[gundb-backend] Importing Gun...");
21239
- const gunModule = await import("./browser-BIvmkBi9.js").then((n2) => n2.b);
21241
+ const gunModule = await import("./browser-yWnjyL8K.js").then((n2) => n2.b);
21240
21242
  Gun = gunModule.default || gunModule;
21241
21243
  console.log("[gundb-backend] Gun imported:", typeof Gun);
21242
21244
  } catch (error) {
@@ -21867,7 +21869,7 @@ class GunDBBackend extends StorageBackend {
21867
21869
  }
21868
21870
  }
21869
21871
  const name = "holosphere";
21870
- const version$1 = "2.0.0-alpha16";
21872
+ const version$1 = "2.0.0-alpha19";
21871
21873
  const description = "Holonic geospatial communication infrastructure combining H3 hexagonal indexing with distributed P2P storage";
21872
21874
  const type = "module";
21873
21875
  const bin = {
@@ -23805,7 +23807,8 @@ async function nostrSubscribeMany(client, pathPrefix, callback, options = {}) {
23805
23807
  const kind2 = options.kind || 3e4;
23806
23808
  const pathParts = pathPrefix.split("/");
23807
23809
  const targetAuthor = pathParts[1] || client.publicKey;
23808
- const subscriptionKey = `${targetAuthor}:${kind2}:${pathPrefix}`;
23810
+ const allAuthors = options.authors || [targetAuthor];
23811
+ const subscriptionKey = `${allAuthors.join(",")}:${kind2}:${pathPrefix}`;
23809
23812
  const existingSub = globalSubscriptions.get(subscriptionKey);
23810
23813
  if (existingSub) {
23811
23814
  existingSub.callbacks.push(callback);
@@ -23833,14 +23836,14 @@ async function nostrSubscribeMany(client, pathPrefix, callback, options = {}) {
23833
23836
  return;
23834
23837
  }
23835
23838
  seenEventIds.add(event.id);
23836
- if (event.pubkey !== targetAuthor) {
23839
+ if (!allAuthors.includes(event.pubkey)) {
23837
23840
  rejectedCount++;
23838
23841
  const now = Date.now();
23839
23842
  if (now - lastLogTime > LOG_INTERVAL) {
23840
23843
  console.warn("[nostrSubscribeMany] ⚠️ Relay not respecting authors filter!", {
23841
23844
  rejectedCount,
23842
23845
  acceptedCount,
23843
- expected: targetAuthor,
23846
+ expectedAuthors: allAuthors.length,
23844
23847
  message: "Consider using a different relay or implementing private relay"
23845
23848
  });
23846
23849
  lastLogTime = now;
@@ -23864,15 +23867,14 @@ async function nostrSubscribeMany(client, pathPrefix, callback, options = {}) {
23864
23867
  }
23865
23868
  }
23866
23869
  };
23867
- const subscriptionStartTime = Math.floor(Date.now() / 1e3);
23870
+ const subscriptionStartTime = Math.floor(Date.now() / 1e3) - 2;
23868
23871
  const dataFilter = {
23869
23872
  kinds: [kind2],
23870
- authors: [targetAuthor],
23871
- // Use target author (holon ID), not client pubkey
23873
+ authors: allAuthors,
23874
+ // Include target author + federated partners
23872
23875
  since: subscriptionStartTime
23873
23876
  // Only get new events after subscription
23874
23877
  };
23875
- console.log("[nostrSubscribeMany] Subscribing to:", { pathPrefix, targetAuthor: targetAuthor.slice(0, 12), clientPubKey: client.publicKey.slice(0, 12) });
23876
23878
  const dataSubscription = await client.subscribe(dataFilter, handleDataEvent);
23877
23879
  let isDocumentHidden = typeof document !== "undefined" && document.hidden;
23878
23880
  let lastVisibilityCheck = subscriptionStartTime;
@@ -24813,11 +24815,15 @@ async function getFederationRegistry(client, appname, options = {}) {
24813
24815
  const registry2 = await readGlobal(client, appname, FEDERATION_TABLE, client.publicKey) || {
24814
24816
  id: client.publicKey,
24815
24817
  federatedWith: [],
24818
+ capabilityWriters: [],
24816
24819
  discoveryEnabled: false,
24817
24820
  autoAccept: false,
24818
24821
  defaultScope: { holonId: "*", lensName: "*" },
24819
24822
  defaultPermissions: ["read"]
24820
24823
  };
24824
+ if (!registry2.capabilityWriters) {
24825
+ registry2.capabilityWriters = [];
24826
+ }
24821
24827
  const partnerIndex = buildPartnerIndex(registry2.federatedWith || []);
24822
24828
  registryCache.set(cacheKey, {
24823
24829
  registry: registry2,
@@ -24886,6 +24892,31 @@ async function getFederatedAuthors(client, appname) {
24886
24892
  const registry2 = await getFederationRegistry(client, appname);
24887
24893
  return registry2.federatedWith.map((p) => p.pubKey);
24888
24894
  }
24895
+ async function addCapabilityWriter(client, appname, writerPubKey) {
24896
+ const registry2 = await getFederationRegistry(client, appname);
24897
+ const exists2 = registry2.capabilityWriters.some((w) => w.pubKey === writerPubKey);
24898
+ if (exists2) {
24899
+ return true;
24900
+ }
24901
+ registry2.capabilityWriters.push({
24902
+ pubKey: writerPubKey,
24903
+ addedAt: Date.now()
24904
+ });
24905
+ return saveFederationRegistry(client, appname, registry2);
24906
+ }
24907
+ async function getCapabilityWriters(client, appname) {
24908
+ const registry2 = await getFederationRegistry(client, appname);
24909
+ return (registry2.capabilityWriters || []).map((w) => w.pubKey);
24910
+ }
24911
+ async function removeCapabilityWriter(client, appname, writerPubKey) {
24912
+ const registry2 = await getFederationRegistry(client, appname);
24913
+ const initialLength = registry2.capabilityWriters.length;
24914
+ registry2.capabilityWriters = registry2.capabilityWriters.filter((w) => w.pubKey !== writerPubKey);
24915
+ if (registry2.capabilityWriters.length === initialLength) {
24916
+ return false;
24917
+ }
24918
+ return saveFederationRegistry(client, appname, registry2);
24919
+ }
24889
24920
  async function getFederatedPartner(client, appname, partnerPubKey) {
24890
24921
  return getPartnerFromIndex(client, appname, partnerPubKey);
24891
24922
  }
@@ -25474,6 +25505,7 @@ function convertToLegacyLensConfig(unifiedConfig) {
25474
25505
  }
25475
25506
  const registry = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
25476
25507
  __proto__: null,
25508
+ addCapabilityWriter,
25477
25509
  addFederatedPartner,
25478
25510
  cleanupExpiredCapabilities,
25479
25511
  convertLegacyLensConfig,
@@ -25482,6 +25514,7 @@ const registry = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProp
25482
25514
  getAccessGrants,
25483
25515
  getAllWriteGrants,
25484
25516
  getCapabilityForAuthor,
25517
+ getCapabilityWriters,
25485
25518
  getFederatedAuthors,
25486
25519
  getFederatedAuthorsForScope,
25487
25520
  getFederatedPartner,
@@ -25494,6 +25527,7 @@ const registry = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProp
25494
25527
  invalidateRegistryCache,
25495
25528
  isSelfCapability,
25496
25529
  migrateToUnifiedGrants,
25530
+ removeCapabilityWriter,
25497
25531
  removeFederatedPartner,
25498
25532
  revokeAccess,
25499
25533
  revokeOutboundCapability,
@@ -28083,7 +28117,7 @@ const socialProtocols = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.def
28083
28117
  validateNostrEvent
28084
28118
  }, Symbol.toStringTag, { value: "Module" }));
28085
28119
  async function createSubscription(client, path, callback, options = {}) {
28086
- const { throttle = 0, filter = null, includeFederated = false, triggerInitial = false, realtimeOnly = true, resolveHolograms = true } = options;
28120
+ const { throttle = 0, filter = null, includeFederated = false, triggerInitial = false, realtimeOnly = true, resolveHolograms = true, appname = null } = options;
28087
28121
  let lastInvoke = 0;
28088
28122
  let timeoutId = null;
28089
28123
  const seenKeys = /* @__PURE__ */ new Set();
@@ -28100,12 +28134,21 @@ async function createSubscription(client, path, callback, options = {}) {
28100
28134
  let resolvedData = data;
28101
28135
  if (resolveHolograms && data && data.hologram === true) {
28102
28136
  try {
28103
- resolvedData = await resolveHologram(client, data);
28137
+ resolvedData = await resolveHologram(client, data, void 0, void 0, { appname });
28104
28138
  if (!resolvedData) {
28139
+ console.debug("[subscription] Hologram resolution returned null, skipping:", {
28140
+ id: data.id,
28141
+ soul: data.soul,
28142
+ target: data.target?.holonId?.slice(0, 12)
28143
+ });
28105
28144
  return;
28106
28145
  }
28107
28146
  } catch (err) {
28108
- console.warn("Failed to resolve hologram in subscription:", err);
28147
+ console.warn("Failed to resolve hologram in subscription:", err, {
28148
+ id: data?.id,
28149
+ soul: data?.soul,
28150
+ target: data?.target?.holonId?.slice(0, 12)
28151
+ });
28109
28152
  return;
28110
28153
  }
28111
28154
  }
@@ -28126,7 +28169,7 @@ async function createSubscription(client, path, callback, options = {}) {
28126
28169
  lastInvoke = now;
28127
28170
  callback(resolvedData, key);
28128
28171
  };
28129
- const subscription = await subscribe(client, path, wrappedCallback, { realtimeOnly });
28172
+ const subscription = await subscribe(client, path, wrappedCallback, { realtimeOnly, ...options.authors && { authors: options.authors } });
28130
28173
  return {
28131
28174
  path,
28132
28175
  unsubscribe: () => {
@@ -38353,7 +38396,7 @@ class ChainManager {
38353
38396
  */
38354
38397
  async _loadEthers() {
38355
38398
  if (!this.ethers) {
38356
- const ethersModule = await import("./index-HW9kbrzC.js");
38399
+ const ethersModule = await import("./index-Bgi_csBR.js");
38357
38400
  this.ethers = ethersModule;
38358
38401
  }
38359
38402
  return this.ethers;
@@ -47144,7 +47187,7 @@ class ContractDeployer {
47144
47187
  */
47145
47188
  async _loadEthers() {
47146
47189
  if (!this.ethers) {
47147
- this.ethers = await import("./index-HW9kbrzC.js");
47190
+ this.ethers = await import("./index-Bgi_csBR.js");
47148
47191
  }
47149
47192
  return this.ethers;
47150
47193
  }
@@ -47530,7 +47573,7 @@ class ContractOperations {
47530
47573
  */
47531
47574
  async _loadEthers() {
47532
47575
  if (!this.ethers) {
47533
- this.ethers = await import("./index-HW9kbrzC.js");
47576
+ this.ethers = await import("./index-Bgi_csBR.js");
47534
47577
  }
47535
47578
  return this.ethers;
47536
47579
  }
@@ -59771,7 +59814,20 @@ class HoloSphereBase extends HoloSphere$1 {
59771
59814
  const isOwnHolon = effectiveWriterPubKey && (holonId === effectiveWriterPubKey || !isPubkeyHolon);
59772
59815
  const capToken = options.capabilityToken || options.capability;
59773
59816
  const actingAsHolon = options.actingAs || options.actingAsHolon;
59774
- if (!isOwnHolon) {
59817
+ if (options.externalWriter) {
59818
+ const writerPubKey = effectiveWriterPubKey;
59819
+ if (writerPubKey && writerPubKey !== holonId) {
59820
+ try {
59821
+ await addCapabilityWriter(this.client, this.config.appName, writerPubKey);
59822
+ this._log("DEBUG", "✅ Registered capability writer", {
59823
+ writerPubKey: writerPubKey.slice(0, 12) + "...",
59824
+ holonId: holonId.slice(0, 12) + "..."
59825
+ });
59826
+ } catch (err) {
59827
+ this._log("WARN", "⚠️ Failed to register capability writer", { error: err.message });
59828
+ }
59829
+ }
59830
+ } else if (!isOwnHolon) {
59775
59831
  if (capToken) {
59776
59832
  const authorized = await this.verifyCapability(capToken, "write", { holonId, lensName });
59777
59833
  if (!authorized) {
@@ -60178,89 +60234,32 @@ class HoloSphereBase extends HoloSphere$1 {
60178
60234
  return this.keyStore.isOwnKey(lensPath);
60179
60235
  }
60180
60236
  /**
60181
- * Recursively resolves holograms (references) to their source data.
60182
- * Handles circular reference detection and local overrides.
60237
+ * Resolves holograms (references) to their source data.
60238
+ * Iterates arrays and filters out invalid entries; delegates individual
60239
+ * hologram resolution (including capability verification and recursive
60240
+ * chain resolution) to federation.resolveHologram().
60183
60241
  *
60184
60242
  * @private
60185
60243
  * @param {Object|Array|null} data - Data that may contain holograms
60186
- * @param {Set<string>} [visited=new Set()] - Set of visited paths for circular detection
60187
60244
  * @returns {Promise<Object|Array|null>} Resolved data with holograms replaced by source data
60188
60245
  */
60189
- async _resolveHolograms(data, visited = /* @__PURE__ */ new Set()) {
60246
+ async _resolveHolograms(data) {
60190
60247
  if (!data) return data;
60191
60248
  if (Array.isArray(data)) {
60192
60249
  const resolved = [];
60193
60250
  for (const item of data) {
60194
- const resolvedItem = await this._resolveHolograms(item, /* @__PURE__ */ new Set());
60251
+ const resolvedItem = await this._resolveHolograms(item);
60195
60252
  if (resolvedItem !== null) {
60196
60253
  resolved.push(resolvedItem);
60197
60254
  }
60198
60255
  }
60199
60256
  return resolved;
60200
60257
  }
60201
- if (data && typeof data === "object") {
60202
- if (data.hologram === true && data.target) {
60203
- const sourcePath = buildPath(
60204
- data.target.appname || this.config.appName,
60205
- data.target.holonId,
60206
- data.target.lensName,
60207
- data.target.dataId
60208
- );
60209
- this._log("DEBUG", "resolving hologram", {
60210
- hologramId: data.id,
60211
- sourcePath,
60212
- targetHolon: data.target.holonId,
60213
- targetLens: data.target.lensName,
60214
- targetDataId: data.target.dataId
60215
- });
60216
- if (visited.has(sourcePath)) {
60217
- this._log("WARN", "Circular hologram reference detected", { sourcePath });
60218
- return null;
60219
- }
60220
- visited.add(sourcePath);
60221
- let resolveOptions = {};
60222
- if (data.target.authorPubKey) {
60223
- resolveOptions.authors = [data.target.authorPubKey];
60224
- resolveOptions.includeAuthor = true;
60225
- }
60226
- const sourceData = await read(this.client, sourcePath, resolveOptions);
60227
- this._log("DEBUG", "hologram source fetched", { found: !!sourceData, sourcePath });
60228
- if (sourceData) {
60229
- let resolvedSource = sourceData;
60230
- if (sourceData.hologram === true && sourceData.target) {
60231
- resolvedSource = await this._resolveHolograms(sourceData, visited);
60232
- if (resolvedSource === null) {
60233
- return null;
60234
- }
60235
- }
60236
- const hologramStructureFields = ["hologram", "soul", "target", "_meta", "id", "capability", "crossHolosphere"];
60237
- const localOverrides = {};
60238
- for (const [k, v] of Object.entries(data)) {
60239
- if (!hologramStructureFields.includes(k)) {
60240
- localOverrides[k] = v;
60241
- }
60242
- }
60243
- const merged = {
60244
- ...resolvedSource,
60245
- ...localOverrides,
60246
- _hologram: {
60247
- isHologram: true,
60248
- soul: data.soul,
60249
- sourceHolon: data.target.holonId,
60250
- source: data.target,
60251
- localOverrides: Object.keys(localOverrides),
60252
- crossHolosphere: data.crossHolosphere || false
60253
- }
60254
- };
60255
- if (resolvedSource._meta) {
60256
- merged._meta = { ...resolvedSource._meta, source: data.target.holonId };
60257
- } else {
60258
- merged._meta = { source: data.target.holonId };
60259
- }
60260
- return merged;
60261
- }
60262
- return null;
60263
- }
60258
+ if (data?.hologram === true && data.target) {
60259
+ return resolveHologram(this.client, data, /* @__PURE__ */ new Set(), [], {
60260
+ appname: this.config.appName,
60261
+ deleteCircular: false
60262
+ });
60264
60263
  }
60265
60264
  return data;
60266
60265
  }
@@ -60360,8 +60359,8 @@ class HoloSphereBase extends HoloSphere$1 {
60360
60359
  this.config.appName
60361
60360
  );
60362
60361
  const fedAuthorsTimeout = new Promise(
60363
- (resolve) => setTimeout(() => resolve([]), 5e3)
60364
- // 5 second timeout, resolve with empty array
60362
+ (resolve) => setTimeout(() => resolve([]), 1e3)
60363
+ // 1 second timeout, resolve with empty array
60365
60364
  );
60366
60365
  const federatedAuthors = await Promise.race([fedAuthorsPromise, fedAuthorsTimeout]);
60367
60366
  this._log("DEBUG", "✅ Got federated authors", { count: federatedAuthors?.length || 0 });
@@ -60372,6 +60371,20 @@ class HoloSphereBase extends HoloSphere$1 {
60372
60371
  } catch (err) {
60373
60372
  this._log("WARN", "Failed to get federated authors", { error: err.message });
60374
60373
  }
60374
+ try {
60375
+ const capWritersPromise = getCapabilityWriters(this.client, this.config.appName);
60376
+ const capWritersTimeout = new Promise(
60377
+ (resolve) => setTimeout(() => resolve([]), 1e3)
60378
+ );
60379
+ const capabilityWriters = await Promise.race([capWritersPromise, capWritersTimeout]);
60380
+ if (capabilityWriters.length > 0) {
60381
+ const existing = readOptions.authors || [this.client.publicKey];
60382
+ readOptions.authors = [.../* @__PURE__ */ new Set([...existing, ...capabilityWriters])];
60383
+ this._log("DEBUG", "Including capability writers", { count: capabilityWriters.length });
60384
+ }
60385
+ } catch (err) {
60386
+ this._log("WARN", "Failed to get capability writers", { error: err.message });
60387
+ }
60375
60388
  }
60376
60389
  const startTime = Date.now();
60377
60390
  let result;
@@ -61373,14 +61386,14 @@ class HoloSphereBase extends HoloSphere$1 {
61373
61386
  throw new TypeError("callback must be a function");
61374
61387
  }
61375
61388
  const path = buildPath(this.config.appName, holonId, lensName);
61376
- const subscriptionOptions = { realtimeOnly: true, ...options };
61389
+ const subscriptionOptions = { realtimeOnly: true, appname: this.config.appName, ...options };
61377
61390
  const subscriptionId = `${holonId}-${lensName}-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
61378
61391
  let innerSubscription = null;
61379
61392
  let unsubscribeCalled = false;
61380
61393
  (async () => {
61381
61394
  try {
61382
- const targetPubkey = await this._resolveHolonToPubkey(holonId);
61383
- const isOtherAuthor = targetPubkey && targetPubkey !== this.client.publicKey;
61395
+ const isPubkeyHolon = typeof holonId === "string" && /^[0-9a-f]{64}$/i.test(holonId);
61396
+ const isOtherAuthor = isPubkeyHolon && holonId !== this.client.publicKey;
61384
61397
  if (isOtherAuthor) {
61385
61398
  const capToken = options.capabilityToken || options.capability;
61386
61399
  if (capToken) {
@@ -61390,23 +61403,24 @@ class HoloSphereBase extends HoloSphere$1 {
61390
61403
  return;
61391
61404
  }
61392
61405
  } else {
61393
- const capability = await this._getCapabilityForAuthor(targetPubkey, { holonId, lensName });
61406
+ const capability = await this._getCapabilityForAuthor(holonId, { holonId, lensName });
61394
61407
  if (!capability) {
61395
61408
  this._log("WARN", "❌ Subscribe: no capability for federated author - skipping", {
61396
61409
  holonId,
61397
61410
  lensName,
61398
- targetPubkey: targetPubkey?.slice(0, 12) + "..."
61411
+ targetPubkey: holonId?.slice(0, 12) + "..."
61399
61412
  });
61400
61413
  return;
61401
61414
  }
61402
61415
  this._log("DEBUG", "✅ Subscribe: capability found for federated author", {
61403
61416
  holonId,
61404
61417
  lensName,
61405
- targetPubkey: targetPubkey?.slice(0, 12) + "..."
61418
+ targetPubkey: holonId?.slice(0, 12) + "..."
61406
61419
  });
61407
61420
  }
61408
61421
  }
61409
61422
  if (unsubscribeCalled) return;
61423
+ subscriptionOptions.authors = [this.client.publicKey];
61410
61424
  const subscription = await createSubscription(
61411
61425
  this.client,
61412
61426
  path,
@@ -61416,8 +61430,25 @@ class HoloSphereBase extends HoloSphere$1 {
61416
61430
  innerSubscription = subscription;
61417
61431
  if (unsubscribeCalled) {
61418
61432
  subscription.unsubscribe();
61419
- } else {
61420
- this.subscriptionRegistry.register(subscriptionId, subscription);
61433
+ return;
61434
+ }
61435
+ this.subscriptionRegistry.register(subscriptionId, subscription);
61436
+ if (!isOtherAuthor) {
61437
+ try {
61438
+ const fedAuthorsPromise = getFederatedAuthors(
61439
+ this.client,
61440
+ this.config.appName
61441
+ );
61442
+ const fedAuthorsTimeout = new Promise(
61443
+ (resolve) => setTimeout(() => resolve([]), 1e3)
61444
+ );
61445
+ const federatedAuthors = await Promise.race([fedAuthorsPromise, fedAuthorsTimeout]);
61446
+ if (federatedAuthors.length > 0) {
61447
+ this._log("DEBUG", "Subscribe: federated authors found post-setup", { count: federatedAuthors.length });
61448
+ }
61449
+ } catch (err) {
61450
+ this._log("WARN", "Failed to get federated authors for subscription", { error: err.message });
61451
+ }
61421
61452
  }
61422
61453
  } catch (err) {
61423
61454
  this._log("ERROR", "Subscription setup failed", { path, error: err.message });
@@ -62001,4 +62032,4 @@ export {
62001
62032
  concatBytes as y,
62002
62033
  dataLength as z
62003
62034
  };
62004
- //# sourceMappingURL=index-B7ERi4ng.js.map
62035
+ //# sourceMappingURL=index-CHfVBEUH.js.map