@interopio/desktop 6.11.0 → 6.12.0

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.
@@ -2944,7 +2944,7 @@
2944
2944
  }
2945
2945
  };
2946
2946
 
2947
- var version$1 = "6.5.2";
2947
+ var version$1 = "6.5.2-fmr-beta";
2948
2948
 
2949
2949
  function prepareConfig$1 (configuration, ext, glue42gd) {
2950
2950
  let nodeStartingContext;
@@ -5664,7 +5664,10 @@
5664
5664
  this._contextIdToName = {};
5665
5665
  delete this._protocolVersion;
5666
5666
  this._contextsTempCache = Object.keys(this._contextNameToData).reduce((cacheSoFar, ctxName) => {
5667
- cacheSoFar[ctxName] = this._contextNameToData[ctxName].context;
5667
+ const contextData = this._contextNameToData[ctxName];
5668
+ if (contextData.isAnnounced && (contextData.activityId || contextData.sentExplicitSubscription)) {
5669
+ cacheSoFar[ctxName] = this._contextNameToData[ctxName].context;
5670
+ }
5668
5671
  return cacheSoFar;
5669
5672
  }, {});
5670
5673
  this._contextNameToData = {};
@@ -11596,21 +11599,12 @@
11596
11599
  const INTEROP_METHOD_RESPONSE_TIMEOUT_MS = 90000;
11597
11600
  const INTEROP_METHOD_WAIT_TIMEOUT_MS = 90000;
11598
11601
 
11599
- // This alphabet uses `A-Za-z0-9_-` symbols.
11600
- // The order of characters is optimized for better gzip and brotli compression.
11601
- // References to the same file (works both for gzip and brotli):
11602
- // `'use`, `andom`, and `rict'`
11603
- // References to the brotli default dictionary:
11604
- // `-26T`, `1983`, `40px`, `75px`, `bush`, `jack`, `mind`, `very`, and `wolf`
11605
11602
  let urlAlphabet =
11606
11603
  'useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict';
11607
-
11608
11604
  let nanoid = (size = 21) => {
11609
11605
  let id = '';
11610
- // A compact alternative for `for (var i = 0; i < step; i++)`.
11611
11606
  let i = size | 0;
11612
11607
  while (i--) {
11613
- // `| 0` is more compact and faster than `Math.floor()`.
11614
11608
  id += urlAlphabet[(Math.random() * 64) | 0];
11615
11609
  }
11616
11610
  return id
@@ -12142,10 +12136,11 @@
12142
12136
  }, 0);
12143
12137
  };
12144
12138
  this._logger.trace(`waiting for window with id ${this._id} to appear`);
12139
+ const timeoutInSeconds = 60;
12145
12140
  const timeout = setTimeout(() => {
12146
- this._logger.trace(`window with id ${this._id} did not appear in 30 sec`);
12141
+ this._logger.trace(`window with id ${this._id} did not appear in ${timeoutInSeconds} sec`);
12147
12142
  done(new Error(`can not find a window with id ${this._id}`));
12148
- }, 30000);
12143
+ }, timeoutInSeconds * 1000);
12149
12144
  const unsub = this._windows.onWindowAdded((w) => {
12150
12145
  if (w.id === this._id) {
12151
12146
  this._logger.trace(`window with id ${this._id} appeared`);
@@ -14967,52 +14962,12 @@
14967
14962
  return w;
14968
14963
  }
14969
14964
  async activate(w) {
14970
- let unFocusChanged;
14971
- let unClosed;
14972
- try {
14973
- const done = new Promise((resolve, reject) => {
14974
- unFocusChanged = w.onFocusChanged(() => {
14975
- resolve();
14976
- });
14977
- unClosed = w.onClose(() => {
14978
- reject(new Error("Window was closed"));
14979
- });
14980
- });
14981
- await Promise.all([this.execute("activate", { windowId: w.id }, "FocusChanged"), done]);
14982
- return w;
14983
- }
14984
- finally {
14985
- if (unFocusChanged) {
14986
- unFocusChanged();
14987
- }
14988
- if (unClosed) {
14989
- unClosed();
14990
- }
14991
- }
14965
+ await this.execute("activate", { windowId: w.id });
14966
+ return w;
14992
14967
  }
14993
14968
  async focus(w) {
14994
- let unFocusChanged;
14995
- let unClosed;
14996
- try {
14997
- const done = new Promise((resolve, reject) => {
14998
- unFocusChanged = w.onFocusChanged(() => {
14999
- resolve();
15000
- });
15001
- unClosed = w.onClose(() => {
15002
- reject(new Error("Window was closed"));
15003
- });
15004
- });
15005
- await Promise.all([this.execute("focus", { windowId: w.id }, "FocusChanged"), done]);
15006
- return w;
15007
- }
15008
- finally {
15009
- if (unFocusChanged) {
15010
- unFocusChanged();
15011
- }
15012
- if (unClosed) {
15013
- unClosed();
15014
- }
15015
- }
14969
+ await this.execute("focus", { windowId: w.id });
14970
+ return w;
15016
14971
  }
15017
14972
  async maximizeRestore(w) {
15018
14973
  await this.execute("maximizeRestore", { windowId: w.id }, "StateChanged");
@@ -17913,7 +17868,7 @@
17913
17868
  });
17914
17869
  }
17915
17870
  leaveChannel(channel) {
17916
- const channelsToLeave = new MultiChannelId(channel);
17871
+ const channelsToLeave = new MultiChannelId(channel !== null && channel !== void 0 ? channel : this.channels);
17917
17872
  channelsToLeave.all().forEach((c) => {
17918
17873
  this.channels = this.channels.filter((ch) => ch !== c);
17919
17874
  });
@@ -17937,35 +17892,37 @@
17937
17892
  }
17938
17893
 
17939
17894
  let interop;
17940
- let windowId;
17895
+ let myInstanceId;
17896
+ let logger;
17941
17897
  const T42_ANNOUNCE_METHOD_NAME = "T42.Channels.Announce";
17942
- async function setupInterop(interopLib, channels) {
17898
+ const T42_COMMAND_METHOD_NAME = "T42.Channels.Command";
17899
+ async function setupInterop(interopLib, channels, loggerAPI) {
17943
17900
  var _a, _b;
17901
+ logger = loggerAPI;
17944
17902
  interop = interopLib;
17945
17903
  if (typeof window !== "undefined") {
17946
17904
  if (window.glue42gd) {
17947
- windowId = window.glue42gd.windowId;
17905
+ myInstanceId = window.glue42gd.windowId;
17948
17906
  }
17949
17907
  }
17950
- if (!windowId) {
17951
- return;
17908
+ if (!myInstanceId) {
17909
+ myInstanceId = interopLib.instance.instance;
17952
17910
  }
17953
- await interop.register("T42.Channels.Command", (args) => {
17911
+ await interop.register(T42_COMMAND_METHOD_NAME, (args) => {
17954
17912
  const command = args.command;
17955
17913
  if (!command) {
17956
17914
  throw new Error("missing command argument");
17957
17915
  }
17916
+ logger.trace(`received command "${command}" with ${JSON.stringify(args)}`);
17958
17917
  if (command === "join") {
17959
17918
  const id = args.channel;
17960
17919
  if (!id) {
17961
17920
  throw new Error("missing argument id");
17962
17921
  }
17963
- channels.joinNoSelectorSwitch(id);
17964
- return;
17922
+ return channels.joinNoSelectorSwitch(id);
17965
17923
  }
17966
17924
  if (command === "leave") {
17967
- channels.leaveNoSelectorSwitch();
17968
- return;
17925
+ return channels.leaveNoSelectorSwitch();
17969
17926
  }
17970
17927
  if (command === "get") {
17971
17928
  const id = channels.current();
@@ -17985,37 +17942,37 @@
17985
17942
  if (!channelsToJoin) {
17986
17943
  throw new Error("missing argument channelsToJoin");
17987
17944
  }
17988
- channels.joinNoSelectorSwitch(new MultiChannelId(channelsToJoin).toString());
17989
- return;
17945
+ return channels.joinNoSelectorSwitch(new MultiChannelId(channelsToJoin).toString());
17990
17946
  }
17991
17947
  if (command === "leave-multi") {
17992
17948
  const channelsToLeave = args.channelsToLeave;
17993
- channels.leaveNoSelectorSwitch(new MultiChannelId(channelsToLeave).toString());
17994
- return;
17949
+ return channels.leaveNoSelectorSwitch(new MultiChannelId(channelsToLeave).toString());
17995
17950
  }
17996
17951
  throw new Error(`unknown command ${command}`);
17997
17952
  });
17998
- const result = await interop.invoke(T42_ANNOUNCE_METHOD_NAME, { swId: windowId, instance: interop.instance.instance }, "best", {
17953
+ const result = await interop.invoke(T42_ANNOUNCE_METHOD_NAME, { swId: myInstanceId, instance: interop.instance.instance }, "best", {
17999
17954
  waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS,
18000
17955
  methodResponseTimeoutMs: INTEROP_METHOD_RESPONSE_TIMEOUT_MS
18001
17956
  });
18002
17957
  if ((_a = result.returned) === null || _a === void 0 ? void 0 : _a.restrictions) {
18003
- channels.handleRestrictionsChanged((_b = result.returned) === null || _b === void 0 ? void 0 : _b.restrictions, windowId);
17958
+ channels.handleRestrictionsChanged((_b = result.returned) === null || _b === void 0 ? void 0 : _b.restrictions, myInstanceId);
18004
17959
  }
17960
+ return result.returned;
18005
17961
  }
18006
17962
  async function sendLeaveChannel(channel, winId) {
18007
- await invoke("leaveChannel", { channel }, winId !== null && winId !== void 0 ? winId : windowId);
17963
+ var _a;
17964
+ await invoke("leaveChannel", { channel }, (_a = winId !== null && winId !== void 0 ? winId : winId) !== null && _a !== void 0 ? _a : myInstanceId);
18008
17965
  }
18009
17966
  async function sendSwitchChannelUI(channel, winId) {
18010
- await invoke("switchChannel", { newChannel: channel }, winId !== null && winId !== void 0 ? winId : windowId);
17967
+ await invoke("switchChannel", { newChannel: channel }, winId !== null && winId !== void 0 ? winId : myInstanceId);
18011
17968
  }
18012
17969
  async function setRestrictions(restrictions) {
18013
17970
  var _a;
18014
- await invoke("restrict", restrictions, (_a = restrictions.windowId) !== null && _a !== void 0 ? _a : windowId);
17971
+ await invoke("restrict", restrictions, (_a = restrictions.windowId) !== null && _a !== void 0 ? _a : myInstanceId);
18015
17972
  }
18016
17973
  async function getRestrictionsByWindow(id) {
18017
17974
  try {
18018
- const result = await invoke("getRestrictions", {}, id !== null && id !== void 0 ? id : windowId);
17975
+ const result = await invoke("getRestrictions", {}, id !== null && id !== void 0 ? id : myInstanceId);
18019
17976
  return result.returned;
18020
17977
  }
18021
17978
  catch (e) {
@@ -18023,37 +17980,47 @@
18023
17980
  }
18024
17981
  async function setRestrictionsForAllChannels(restrictions) {
18025
17982
  var _a;
18026
- await invoke("restrictAll", restrictions, (_a = restrictions.windowId) !== null && _a !== void 0 ? _a : windowId);
17983
+ await invoke("restrictAll", restrictions, (_a = restrictions.windowId) !== null && _a !== void 0 ? _a : myInstanceId);
18027
17984
  }
18028
- async function getWindowsWithChannels(filter) {
17985
+ async function getChannelsInfo(filter) {
18029
17986
  const result = await invoke("getChannelsInfo", { filter });
18030
17987
  return result.returned;
18031
17988
  }
18032
17989
  async function addOrRemoveChannel(command, id, color, label) {
18033
17990
  await invoke(command, { id, color, label });
18034
17991
  }
18035
- async function getChannelsMode(config, i) {
17992
+ async function getChannelInitInfo(config, i) {
18036
17993
  if (typeof config.operationMode !== "boolean" && typeof config.operationMode === "string") {
18037
17994
  validateMode(config.operationMode);
18038
- return config.operationMode;
17995
+ return { mode: config.operationMode, initialChannel: undefined };
18039
17996
  }
18040
17997
  try {
18041
17998
  const result = await i.invoke(T42_ANNOUNCE_METHOD_NAME, { command: "getChannelsMode" }, "best", {
18042
17999
  waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS,
18043
18000
  methodResponseTimeoutMs: INTEROP_METHOD_RESPONSE_TIMEOUT_MS,
18044
18001
  });
18002
+ const initialChannel = result.returned.initialChannel;
18045
18003
  if (result.returned.mode === "single") {
18046
- return "single";
18004
+ return {
18005
+ mode: "single",
18006
+ initialChannel
18007
+ };
18047
18008
  }
18048
18009
  else if (result.returned.mode === "multi") {
18049
- return "multi";
18010
+ return {
18011
+ mode: "multi",
18012
+ initialChannel
18013
+ };
18050
18014
  }
18051
18015
  else {
18052
- return "single";
18016
+ return {
18017
+ mode: "single",
18018
+ initialChannel
18019
+ };
18053
18020
  }
18054
18021
  }
18055
18022
  catch (e) {
18056
- return "single";
18023
+ return { mode: "single", initialChannel: undefined };
18057
18024
  }
18058
18025
  }
18059
18026
  function invoke(command, data, swId) {
@@ -18105,6 +18072,9 @@
18105
18072
  if (contextData[LATEST_FDC3_TYPE]) {
18106
18073
  return this.getContextWithFdc3Data(contextData);
18107
18074
  }
18075
+ else {
18076
+ delete contextData[LATEST_FDC3_TYPE];
18077
+ }
18108
18078
  return contextData;
18109
18079
  }
18110
18080
  updateChannel(name, data) {
@@ -18154,6 +18124,10 @@
18154
18124
  throw new Error("setPaths is not supported!");
18155
18125
  }
18156
18126
  }
18127
+ clearContextData(name) {
18128
+ const contextName = this.createContextName(name);
18129
+ return this.contexts.update(contextName, { data: {}, [LATEST_FDC3_TYPE]: undefined });
18130
+ }
18157
18131
  isChannel(name) {
18158
18132
  return this.all().some((channelName) => channelName === name);
18159
18133
  }
@@ -18270,6 +18244,7 @@
18270
18244
  unsubscribe() {
18271
18245
  if (this.unsubscribeFunc) {
18272
18246
  this.unsubscribeFunc();
18247
+ this.unsubscribeFunc = undefined;
18273
18248
  }
18274
18249
  }
18275
18250
  }
@@ -18284,9 +18259,10 @@
18284
18259
  };
18285
18260
 
18286
18261
  class ChannelsImpl {
18287
- constructor(interop, getWindows, logger) {
18262
+ constructor(interop, getWindowsAPI, getAppManagerAPI, logger) {
18288
18263
  this.interop = interop;
18289
- this.getWindows = getWindows;
18264
+ this.getWindowsAPI = getWindowsAPI;
18265
+ this.getAppManagerAPI = getAppManagerAPI;
18290
18266
  this.logger = logger;
18291
18267
  this.subsKey = "subs";
18292
18268
  this.changedKey = "changed";
@@ -18309,17 +18285,20 @@
18309
18285
  }
18310
18286
  return result;
18311
18287
  }
18312
- init(shared, mode) {
18288
+ async init(shared, mode, initial) {
18313
18289
  this.mode = mode;
18314
18290
  this.shared = shared;
18315
18291
  this.shared.subscribe(this.handler.bind(this));
18316
18292
  this.subscribeForChannelRestrictionsChange();
18293
+ let initialChannel = initial;
18317
18294
  if (typeof window !== "undefined" && typeof window.glue42gd !== "undefined") {
18318
- const initial = window.glue42gd.initialChannel;
18319
- this.currentChannelID = this.getID(initial);
18320
- if (this.currentChannelID.isJoinedToAnyChannel) {
18321
- this.joinNoSelectorSwitch(this.currentChannelID.toString());
18322
- }
18295
+ initialChannel = window.glue42gd.initialChannel;
18296
+ }
18297
+ this.currentChannelID = this.getID(initialChannel);
18298
+ this.logger.trace(`initialized with mode: "${mode}" and initial channel: "${initialChannel}"`);
18299
+ if (this.currentChannelID.isJoinedToAnyChannel) {
18300
+ this.logger.trace(`joining initial channel: "${this.currentChannelID.toString()}"`);
18301
+ await this.joinNoSelectorSwitch(this.currentChannelID.toString());
18323
18302
  }
18324
18303
  }
18325
18304
  subscribe(callback, options) {
@@ -18384,11 +18363,34 @@
18384
18363
  if (!this.shared.isChannel(channelName)) {
18385
18364
  return Promise.reject(new Error(`A channel with name: ${channelName} doesn't exist!`));
18386
18365
  }
18387
- const canPublish = (await this.getRestrictionsByChannel(channelName)).write;
18388
- if (!canPublish) {
18389
- throw new Error(`Window does not have permission to write to channel ${this.currentChannelID.toString()}`);
18366
+ if (this.mode === "multi") {
18367
+ const channelsToPublish = new MultiChannelId(channelName).all();
18368
+ const restrictedChannels = [];
18369
+ for (const cn of channelsToPublish) {
18370
+ const canPublish = (await this.getRestrictionsByChannel(cn)).write;
18371
+ if (!canPublish) {
18372
+ restrictedChannels.push(cn);
18373
+ continue;
18374
+ }
18375
+ await this.shared.updateData(cn, data);
18376
+ }
18377
+ if (restrictedChannels.length > 0) {
18378
+ const restrictedChannelsErr = `Unable to publish due to restrictions to the following channels: ${restrictedChannels.join(", ")}`;
18379
+ if (restrictedChannels.length === channelsToPublish.length) {
18380
+ throw new Error(restrictedChannelsErr);
18381
+ }
18382
+ else {
18383
+ this.logger.warn(restrictedChannelsErr);
18384
+ }
18385
+ }
18386
+ }
18387
+ else {
18388
+ const canPublish = (await this.getRestrictionsByChannel(channelName)).write;
18389
+ if (!canPublish) {
18390
+ throw new Error(`Window does not have permission to write to channel ${channelName}`);
18391
+ }
18392
+ return this.shared.updateData(channelName, data);
18390
18393
  }
18391
- return this.shared.updateData(channelName, data);
18392
18394
  }
18393
18395
  async setPaths(paths, name) {
18394
18396
  if (name) {
@@ -18471,14 +18473,30 @@
18471
18473
  async join(name, windowId) {
18472
18474
  if (windowId !== undefined && windowId !== null) {
18473
18475
  this.validateWindowIdArg(windowId);
18476
+ this.logger.trace(`joining channel ${name} for window: ${windowId}`);
18474
18477
  return sendSwitchChannelUI(name, windowId);
18475
18478
  }
18476
18479
  return this.joinCore(name);
18477
18480
  }
18478
- async joinNoSelectorSwitch(id) {
18479
- return this.joinCore(id, false);
18481
+ async joinNoSelectorSwitch(channelName) {
18482
+ this.logger.trace(`joining channel "${channelName}" from command`);
18483
+ return this.joinCore(channelName, false);
18480
18484
  }
18481
- leave(windowId, channelName) {
18485
+ leave(options) {
18486
+ this.logger.trace(`leaving channel with options: ${JSON.stringify(options)}`);
18487
+ let windowId;
18488
+ let channelName;
18489
+ if (typeof options === "string") {
18490
+ windowId = options;
18491
+ }
18492
+ else if (typeof options === "object" && !Array.isArray(options) && options !== null && options !== undefined) {
18493
+ if (options.windowId) {
18494
+ windowId = options.windowId;
18495
+ }
18496
+ if (options.channel) {
18497
+ channelName = options.channel;
18498
+ }
18499
+ }
18482
18500
  if (this.mode === "multi") {
18483
18501
  return this.leaveWhenMulti(channelName, windowId);
18484
18502
  }
@@ -18487,7 +18505,8 @@
18487
18505
  }
18488
18506
  }
18489
18507
  leaveNoSelectorSwitch(channelName) {
18490
- return this.leave(undefined, channelName);
18508
+ this.logger.trace(`leaving channel "${channelName}" from command`);
18509
+ return this.leaveCore(false, channelName);
18491
18510
  }
18492
18511
  current() {
18493
18512
  return this.currentChannelID.toString();
@@ -18503,13 +18522,18 @@
18503
18522
  if (typeof callback !== "function") {
18504
18523
  throw new Error("Please provide the callback as a function!");
18505
18524
  }
18525
+ let timeoutId;
18506
18526
  const current = this.current();
18507
18527
  if (current) {
18508
- setTimeout(() => {
18528
+ timeoutId = setTimeout(() => {
18509
18529
  callback(this.myChannels());
18510
18530
  }, 0);
18511
18531
  }
18512
- return this.registry.add(this.channelsChangedKey, callback);
18532
+ const un = this.registry.add(this.channelsChangedKey, callback);
18533
+ return () => {
18534
+ un();
18535
+ clearTimeout(timeoutId);
18536
+ };
18513
18537
  }
18514
18538
  changed(callback) {
18515
18539
  if (typeof callback !== "function") {
@@ -18556,14 +18580,16 @@
18556
18580
  meta: info.meta || {},
18557
18581
  data: info.data || {}
18558
18582
  };
18559
- await this.shared.updateChannel(info.name, context);
18583
+ this.logger.trace(`adding channel: ${info.name}`);
18560
18584
  await addOrRemoveChannel("addChannel", info.name, info.meta.color, (_a = info.meta) === null || _a === void 0 ? void 0 : _a.label);
18585
+ await this.shared.updateChannel(info.name, context);
18561
18586
  return context;
18562
18587
  }
18563
18588
  async remove(channel) {
18564
18589
  if (typeof channel !== "string") {
18565
18590
  throw new Error("Please provide the channel name as a string!");
18566
18591
  }
18592
+ this.logger.trace(`removing channel: ${channel}`);
18567
18593
  await this.shared.remove(channel);
18568
18594
  await addOrRemoveChannel("removeChannel", channel);
18569
18595
  }
@@ -18575,17 +18601,18 @@
18575
18601
  async getWindowsWithChannels(filter) {
18576
18602
  this.validateWindowsWithChannelsFilter(filter);
18577
18603
  try {
18578
- const info = await getWindowsWithChannels(filter);
18579
- const windows = this.getWindows();
18604
+ const info = await getChannelsInfo(filter);
18605
+ const windowsAPI = this.getWindowsAPI();
18580
18606
  if (info === null || info === void 0 ? void 0 : info.windows) {
18581
- return info.windows.map((windowInfo) => {
18582
- const window = windows.findById(windowInfo.windowId);
18583
- return {
18607
+ return info.windows.reduce((memo, windowInfo) => {
18608
+ const window = windowsAPI.findById(windowInfo.windowId);
18609
+ memo.push({
18584
18610
  window,
18585
18611
  channel: windowInfo.channel,
18586
18612
  application: windowInfo.application
18587
- };
18588
- });
18613
+ });
18614
+ return memo;
18615
+ }, []);
18589
18616
  }
18590
18617
  }
18591
18618
  catch (er) {
@@ -18613,6 +18640,20 @@
18613
18640
  windowId
18614
18641
  });
18615
18642
  }
18643
+ async clearChannelData(channel) {
18644
+ const channelName = typeof channel === "string" ? channel : this.currentChannelID.toString();
18645
+ if (!channelName) {
18646
+ return;
18647
+ }
18648
+ if (!this.shared.isChannel(channelName)) {
18649
+ return;
18650
+ }
18651
+ const canPublish = (await this.getRestrictionsByChannel(channelName)).write;
18652
+ if (!canPublish) {
18653
+ return;
18654
+ }
18655
+ return this.shared.clearContextData(channelName);
18656
+ }
18616
18657
  handler(data, context, updaterId) {
18617
18658
  if (!context && !updaterId) {
18618
18659
  this.lastUpdate = undefined;
@@ -18623,22 +18664,28 @@
18623
18664
  this.registry.execute(this.subsKey, data, context, updaterId);
18624
18665
  }
18625
18666
  async joinCore(name, changeSelector = true) {
18667
+ this.logger.trace(`joining channel "${name}" ${changeSelector ? "" : "from command"}`);
18626
18668
  if (typeof name !== "string") {
18627
18669
  throw new Error("Please provide the channel name as a string!");
18628
18670
  }
18629
18671
  const newId = this.getID(name);
18630
- if (!this.isInitialJoin && this.currentChannelID.equals(newId)) {
18672
+ if (!this.isInitialJoin && this.currentChannelID.isOnChannel(newId.toString())) {
18673
+ this.logger.trace(`already on channel: "${name}" ${changeSelector ? "" : "from command"}`);
18631
18674
  return;
18632
18675
  }
18633
18676
  this.isInitialJoin = false;
18634
18677
  await Promise.all(newId.all().map((n) => this.verifyChannelExists(n)));
18635
18678
  this.currentChannelID.joinChannel(name);
18636
18679
  this.lastUpdate = undefined;
18680
+ this.logger.trace(`switching channel context to: "${name}" ${changeSelector ? "" : "from command"}`);
18637
18681
  await this.shared.switchChannel(this.currentChannelID.toString());
18638
18682
  if (changeSelector) {
18683
+ this.logger.trace(`switching UI channel to: "${name}" ${changeSelector ? "" : "from command"}`);
18639
18684
  await sendSwitchChannelUI(name);
18685
+ this.logger.trace(`switched UI channel to: "${name}" ${changeSelector ? "" : "from command"}`);
18640
18686
  }
18641
18687
  this.raiseChannelsChangedEvents();
18688
+ this.logger.trace(`joined channel: ${name} ${changeSelector ? "" : "from command"} - current channel/s: ${this.currentChannelID.toString()}`);
18642
18689
  }
18643
18690
  async verifyChannelExists(name) {
18644
18691
  const doesChannelExist = (channelName) => {
@@ -18663,21 +18710,46 @@
18663
18710
  }
18664
18711
  }
18665
18712
  async leaveCore(changeSelector = true, channelID) {
18713
+ if (!this.currentChannelID.isJoinedToAnyChannel) {
18714
+ this.logger.trace(`leave called ${changeSelector ? "" : "from command"} when not joined to any channel change selector`);
18715
+ return;
18716
+ }
18717
+ if (channelID && !this.currentChannelID.isOnChannel(channelID)) {
18718
+ this.logger.trace(`leave called ${changeSelector ? "" : "from command"} when not joined to channel: "${channelID}"`);
18719
+ return;
18720
+ }
18721
+ this.logger.trace(`leaving context channel: "${channelID}" ${changeSelector ? "" : "from command"}`);
18666
18722
  this.currentChannelID.leaveChannel(channelID);
18667
18723
  await this.shared.leave(channelID);
18724
+ this.lastUpdate = undefined;
18668
18725
  this.raiseChannelsChangedEvents();
18669
18726
  if (changeSelector) {
18727
+ this.logger.trace(`switching UI channel to: "${channelID}" ${changeSelector ? "" : "from command"}`);
18670
18728
  await sendSwitchChannelUI(this.currentChannelID.toString());
18729
+ this.logger.trace(`switched UI channel to: "${channelID}" ${changeSelector ? "" : "from command"}`);
18671
18730
  }
18731
+ this.logger.trace(`left single channel: "${channelID}" ${changeSelector ? "" : "from command"} - current channel/s: "${this.currentChannelID.toString()}"`);
18672
18732
  return Promise.resolve();
18673
18733
  }
18674
18734
  async leaveCoreMulti(changeSelector = true, channelID) {
18675
- this.currentChannelID.leaveChannel(channelID);
18676
- await this.shared.leave(channelID);
18735
+ this.logger.trace(`leaving multi channel: "${channelID.toString()}" ${changeSelector ? "" : "from command"}`);
18736
+ const currentChannels = this.currentChannelID.all();
18737
+ const isJoinedToChannel = currentChannels.some((c) => channelID.isOnChannel(c));
18738
+ if (!isJoinedToChannel || !this.currentChannelID.isJoinedToAnyChannel) {
18739
+ this.logger.trace(`leave called ${changeSelector ? "" : "from command"} when not joined to any channel`);
18740
+ return;
18741
+ }
18742
+ const channelName = channelID.toString();
18743
+ this.currentChannelID.leaveChannel(channelName);
18744
+ await this.shared.leave(channelName);
18745
+ this.lastUpdate = undefined;
18677
18746
  this.raiseChannelsChangedEvents();
18678
18747
  if (changeSelector) {
18679
- sendLeaveChannel(channelID);
18748
+ this.logger.trace(`switching UI channel to: "${channelName}" ${changeSelector ? "" : "from command"}`);
18749
+ await sendLeaveChannel(channelName);
18750
+ this.logger.trace(`switched UI channel to: "${channelName}" ${changeSelector ? "" : "from command"}`);
18680
18751
  }
18752
+ this.logger.trace(`left multi channel: "${channelName}" ${changeSelector ? "" : "from command"} - current channel/s: ${this.currentChannelID.toString()}`);
18681
18753
  return Promise.resolve();
18682
18754
  }
18683
18755
  raiseChannelsChangedEvents() {
@@ -18705,9 +18777,11 @@
18705
18777
  return;
18706
18778
  }
18707
18779
  this.onRestrictionsChangedSub = this.registry.add("restrictions-changed", ({ restrictions }) => {
18780
+ this.logger.trace(`restrictions changed - ${JSON.stringify(restrictions)}`);
18708
18781
  this.pendingRestrictionCallbacks.forEach(({ cb, channelName }, id) => {
18709
18782
  const currentChannel = restrictions.channels.find((c) => c.name === channelName);
18710
18783
  if (!currentChannel) {
18784
+ this.logger.trace(`channel "${channelName}" not found in restrictions`);
18711
18785
  return;
18712
18786
  }
18713
18787
  if (currentChannel.read) {
@@ -18723,6 +18797,7 @@
18723
18797
  }
18724
18798
  subscribeForChannelRestrictionsChange() {
18725
18799
  this.registry.add("restrictions-changed", (r) => {
18800
+ this.logger.trace(`channel restrictions changed - ${JSON.stringify(r.restrictions)}`);
18726
18801
  this.channelRestrictions = r.restrictions;
18727
18802
  });
18728
18803
  }
@@ -18887,21 +18962,28 @@
18887
18962
  }
18888
18963
  leaveWhenSingle(channelName, windowId) {
18889
18964
  if (windowId) {
18965
+ this.logger.trace(`leaving single channel "${channelName}" for window: "${windowId}"`);
18890
18966
  return sendSwitchChannelUI(undefined, windowId);
18891
18967
  }
18968
+ this.logger.trace(`leaving single channel "${channelName}" for our window`);
18892
18969
  return this.leaveCore(true, channelName);
18893
18970
  }
18894
18971
  async leaveWhenMulti(channelName, windowId) {
18895
18972
  if (windowId) {
18973
+ this.logger.trace(`leaving multi channel "${channelName}" for window: "${windowId}"`);
18896
18974
  return sendLeaveChannel(channelName, windowId);
18897
18975
  }
18898
- return this.leaveCoreMulti(true, channelName);
18976
+ else {
18977
+ const channelId = channelName ? new MultiChannelId(channelName) : this.currentChannelID;
18978
+ this.logger.trace(`leaving multi channel "${channelId.toString()}" for our window`);
18979
+ return this.leaveCoreMulti(true, channelId);
18980
+ }
18899
18981
  }
18900
18982
  validateWindowIdArg(windowId) {
18901
18983
  if (typeof windowId !== "string") {
18902
18984
  throw new Error("The window ID must be a non-empty string!");
18903
18985
  }
18904
- const windows = this.getWindows();
18986
+ const windows = this.getWindowsAPI();
18905
18987
  if (!windows.findById(windowId)) {
18906
18988
  throw new Error(`Window with ID "${windowId}" doesn't exist!`);
18907
18989
  }
@@ -18951,18 +19033,18 @@
18951
19033
  }
18952
19034
  }
18953
19035
 
18954
- function factory$4(config, contexts, agm, getWindows, logger) {
18955
- const channelsReadyPromise = getChannelsMode(config, agm)
18956
- .then(async (mode) => {
19036
+ function factory$4(config, contexts, agm, getWindowsAPI, getAppManagerAPI, logger) {
19037
+ const channelsReadyPromise = getChannelInitInfo(config, agm)
19038
+ .then(async ({ mode, initialChannel }) => {
18957
19039
  const sharedContexts = mode === "single" ? new SharedContextSubscriber(contexts) : new MultiSharedContextSubscriber(contexts);
18958
19040
  if (mode === "multi") {
18959
19041
  logger.info(`multi-channel mode enabled`);
18960
19042
  }
18961
- channels.init(sharedContexts, mode);
18962
- await setupInterop(agm, channels);
19043
+ await channels.init(sharedContexts, mode, initialChannel);
19044
+ await setupInterop(agm, channels, logger);
18963
19045
  return true;
18964
19046
  });
18965
- const channels = new ChannelsImpl(agm, getWindows, logger);
19047
+ const channels = new ChannelsImpl(agm, getWindowsAPI, getAppManagerAPI, logger);
18966
19048
  return {
18967
19049
  subscribe: channels.subscribe.bind(channels),
18968
19050
  subscribeFor: channels.subscribeFor.bind(channels),
@@ -18976,6 +19058,7 @@
18976
19058
  leave: channels.leave.bind(channels),
18977
19059
  restrict: channels.restrict.bind(channels),
18978
19060
  getRestrictions: channels.getRestrictions.bind(channels),
19061
+ clearChannelData: channels.clearChannelData.bind(channels),
18979
19062
  restrictAll: channels.restrictAll.bind(channels),
18980
19063
  current: channels.current.bind(channels),
18981
19064
  my: channels.my.bind(channels),
@@ -19093,7 +19176,7 @@
19093
19176
  };
19094
19177
  }
19095
19178
 
19096
- var version = "6.11.0";
19179
+ var version = "6.12.0";
19097
19180
 
19098
19181
  var prepareConfig = (options) => {
19099
19182
  function getLibConfig(value, defaultMode, trueMode) {
@@ -22920,7 +23003,7 @@
22920
23003
  logger.error("Channels library requires Contexts library to be initialized.");
22921
23004
  return;
22922
23005
  }
22923
- _channels = factory$4({ operationMode: glueConfig.channels.operationMode }, core.contexts, core.agm, () => _windows, logger);
23006
+ _channels = factory$4({ operationMode: glueConfig.channels.operationMode }, core.contexts, core.agm, () => _windows, () => _appManager, logger);
22924
23007
  debugLog(_channels);
22925
23008
  return _channels;
22926
23009
  }