@ai-matrx/summon 0.1.7 → 0.1.8

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 (50) hide show
  1. package/CHANGELOG.md +15 -2
  2. package/dist/gate-DUvE-Cc1.d.cts +399 -0
  3. package/dist/gate-DUvE-Cc1.d.ts +399 -0
  4. package/dist/handles.cjs +1 -0
  5. package/dist/handles.cjs.map +1 -1
  6. package/dist/handles.d.cts +3 -61
  7. package/dist/handles.d.ts +3 -61
  8. package/dist/handles.js +1 -0
  9. package/dist/handles.js.map +1 -1
  10. package/dist/helpers-2NY1ha0V.d.cts +63 -0
  11. package/dist/helpers-2NY1ha0V.d.ts +63 -0
  12. package/dist/index.cjs +194 -159
  13. package/dist/index.cjs.map +1 -1
  14. package/dist/index.d.cts +9 -355
  15. package/dist/index.d.ts +9 -355
  16. package/dist/index.js +200 -165
  17. package/dist/index.js.map +1 -1
  18. package/dist/instanceBody-CgZAFnic.d.cts +23 -0
  19. package/dist/instanceBody-CgZAFnic.d.ts +23 -0
  20. package/dist/open.cjs +408 -0
  21. package/dist/open.cjs.map +1 -0
  22. package/dist/open.d.cts +22 -0
  23. package/dist/open.d.ts +22 -0
  24. package/dist/open.js +375 -0
  25. package/dist/open.js.map +1 -0
  26. package/dist/react.cjs +249 -352
  27. package/dist/react.cjs.map +1 -1
  28. package/dist/react.d.cts +11 -151
  29. package/dist/react.d.ts +11 -151
  30. package/dist/react.js +210 -306
  31. package/dist/react.js.map +1 -1
  32. package/dist/root.cjs +277 -0
  33. package/dist/root.cjs.map +1 -0
  34. package/dist/root.d.cts +175 -0
  35. package/dist/root.d.ts +175 -0
  36. package/dist/root.js +254 -0
  37. package/dist/root.js.map +1 -0
  38. package/dist/window-host.cjs +11 -2
  39. package/dist/window-host.cjs.map +1 -1
  40. package/dist/window-host.d.cts +1 -0
  41. package/dist/window-host.d.ts +1 -0
  42. package/dist/window-host.js +11 -2
  43. package/dist/window-host.js.map +1 -1
  44. package/dist/window.cjs +2 -1
  45. package/dist/window.cjs.map +1 -1
  46. package/dist/window.d.cts +3 -2
  47. package/dist/window.d.ts +3 -2
  48. package/dist/window.js +2 -1
  49. package/dist/window.js.map +1 -1
  50. package/package.json +28 -5
package/dist/index.js CHANGED
@@ -101,16 +101,108 @@ function resetOverlayRegistry() {
101
101
  }
102
102
 
103
103
  // src/core/overlaysSlice.ts
104
- import { createSelector, createSlice } from "@reduxjs/toolkit";
104
+ import { createSlice } from "@reduxjs/toolkit";
105
+
106
+ // src/open/actions.ts
107
+ function creator(type, build) {
108
+ const create = (...args) => ({ type, payload: build(...args) });
109
+ return Object.assign(create, {
110
+ type,
111
+ toString: () => type,
112
+ match: (action) => typeof action === "object" && action !== null && action.type === type
113
+ });
114
+ }
115
+ function isPlainRecord(value) {
116
+ return typeof value === "object" && value !== null && !Array.isArray(value);
117
+ }
118
+ function stripFunctions(overlayId, data) {
119
+ if (!isPlainRecord(data)) return data;
120
+ const offenders = Object.keys(data).filter((key) => typeof data[key] === "function");
121
+ if (offenders.length === 0) return data;
122
+ console.error(
123
+ `[summon] BUG: function value(s) in openOverlay data for "${overlayId}" (keys: ${offenders.join(", ")}). Functions cannot travel through Redux \u2014 the handler would NEVER fire. Register a handle (@ai-matrx/summon/handles) and pass its id string instead. The offending key(s) were stripped from state.`
124
+ );
125
+ const cleaned = { ...data };
126
+ for (const key of offenders) delete cleaned[key];
127
+ return cleaned;
128
+ }
129
+ function rawOpen(payload) {
130
+ const raw = { overlayId: payload.overlayId };
131
+ if (payload.instanceId !== void 0) raw.instanceId = payload.instanceId;
132
+ if (payload.data !== void 0) raw.data = stripFunctions(payload.overlayId, payload.data);
133
+ const defaults = getOverlayMeta(payload.overlayId)?.defaults;
134
+ if (isPlainRecord(defaults)) raw.defaults = stripFunctions(payload.overlayId, defaults);
135
+ return raw;
136
+ }
137
+ var O = "overlays/";
138
+ var openOverlay = creator(O + "openOverlay", (payload) => rawOpen(payload));
139
+ var closeOverlay = creator(
140
+ O + "closeOverlay",
141
+ (payload) => payload.instanceId === void 0 ? { overlayId: payload.overlayId } : { overlayId: payload.overlayId, instanceId: payload.instanceId }
142
+ );
143
+ var toggleOverlay = creator(O + "toggleOverlay", (payload) => rawOpen(payload));
144
+ var closeAllInstancesOfOverlay = creator(
145
+ O + "closeAllInstancesOfOverlay",
146
+ (payload) => ({ overlayId: payload.overlayId })
147
+ );
148
+ function overlayIdsBoundToPage() {
149
+ return allOverlayMeta().filter((meta) => meta.closesOnNavigation === true).map((meta) => meta.id);
150
+ }
151
+ var closeOverlaysBoundToPage = creator(
152
+ O + "closeOverlaysBoundToPage",
153
+ (payload) => ({
154
+ overlayIds: [...payload?.overlayIds ?? overlayIdsBoundToPage()]
155
+ })
156
+ );
157
+ var closeAllOverlays = creator(O + "closeAllOverlays", () => void 0);
158
+ var pruneStaleInstances = creator(O + "pruneStaleInstances", (payload) => payload);
159
+ var W = "windowManager/";
160
+ var pass = () => (payload) => payload;
161
+ var focusWindow = creator(W + "focusWindow", pass());
162
+ var restoreWindow = creator(W + "restoreWindow", pass());
163
+ var toggleWindowsHidden = creator(W + "toggleWindowsHidden", () => void 0);
164
+ var restoreAll = creator(W + "restoreAll", () => void 0);
165
+ var minimizeAll = creator(W + "minimizeAll", pass());
166
+
167
+ // src/open/selectors.ts
105
168
  import { globalSlot as globalSlot2 } from "@ai-matrx/kit/global-slot";
169
+ var CLOSED = Object.freeze({ isOpen: false, data: null });
170
+ var EMPTY = Object.freeze([]);
171
+ var selectOverlay = (state2, overlayId, instanceId = DEFAULT_INSTANCE_ID) => state2.overlays?.overlays[overlayId]?.[instanceId] ?? CLOSED;
172
+ var selectIsOverlayOpen = (state2, overlayId, instanceId = DEFAULT_INSTANCE_ID) => selectOverlay(state2, overlayId, instanceId).isOpen;
173
+ var selectOverlayData = (state2, overlayId, instanceId = DEFAULT_INSTANCE_ID) => selectOverlay(state2, overlayId, instanceId).data;
174
+ var openCache = () => globalSlot2("ai-matrx.summon.openInstances", () => /* @__PURE__ */ new Map());
175
+ var selectOpenInstances = (state2, overlayId) => {
176
+ const bucket = state2.overlays?.overlays[overlayId];
177
+ const cache = openCache();
178
+ const hit = cache.get(overlayId);
179
+ if (hit && hit.bucket === bucket) return hit.result;
180
+ let result = EMPTY;
181
+ if (bucket) {
182
+ const open = [];
183
+ for (const [instanceId, inst] of Object.entries(bucket)) if (inst.isOpen) open.push({ instanceId, data: inst.data });
184
+ if (open.length > 0) result = open;
185
+ }
186
+ cache.set(overlayId, { bucket, result });
187
+ return result;
188
+ };
189
+ function listOpenInstanceKeys(state2) {
190
+ const keys = [];
191
+ for (const [overlayId, bucket] of Object.entries(state2.overlays?.overlays ?? {})) {
192
+ for (const [instanceId, inst] of Object.entries(bucket)) if (inst.isOpen) keys.push(`${overlayId}:${instanceId}`);
193
+ }
194
+ return keys;
195
+ }
196
+
197
+ // src/core/overlaysSlice.ts
106
198
  var initialState = { overlays: {} };
107
- function isPlainRecord(value) {
199
+ function isPlainRecord2(value) {
108
200
  return typeof value === "object" && value !== null && !Array.isArray(value);
109
201
  }
110
202
  function withDefaults(data, defaults) {
111
203
  if (!defaults) return data ?? null;
112
204
  if (data === void 0 || data === null) return { ...defaults };
113
- if (isPlainRecord(data)) return { ...defaults, ...data };
205
+ if (isPlainRecord2(data)) return { ...defaults, ...data };
114
206
  return data;
115
207
  }
116
208
  function closeInstance(state2, overlayId, instanceId) {
@@ -210,96 +302,11 @@ var overlaysSlice = createSlice({
210
302
  });
211
303
  var overlaysReducer = overlaysSlice.reducer;
212
304
  var overlaysRawActions = overlaysSlice.actions;
213
- function stripFunctionsFromOverlayData(overlayId, data) {
214
- if (!isPlainRecord(data)) return data;
215
- const offenders = Object.keys(data).filter((key) => typeof data[key] === "function");
216
- if (offenders.length === 0) return data;
217
- console.error(
218
- `[summon] BUG: function value(s) in openOverlay data for "${overlayId}" (keys: ${offenders.join(", ")}). Functions cannot travel through Redux \u2014 the handler would NEVER fire. Register a handle (@ai-matrx/summon/handles) and pass its id string instead. The offending key(s) were stripped from state.`
219
- );
220
- const cleaned = { ...data };
221
- for (const key of offenders) delete cleaned[key];
222
- return cleaned;
223
- }
224
- function rawOpenPayload(payload) {
225
- const raw = { overlayId: payload.overlayId };
226
- if (payload.instanceId !== void 0) raw.instanceId = payload.instanceId;
227
- if (payload.data !== void 0) raw.data = stripFunctionsFromOverlayData(payload.overlayId, payload.data);
228
- const defaults = getOverlayMeta(payload.overlayId)?.defaults;
229
- if (isPlainRecord(defaults)) {
230
- raw.defaults = stripFunctionsFromOverlayData(payload.overlayId, defaults);
231
- }
232
- return raw;
233
- }
234
- function withMatcher(create, raw) {
235
- return Object.assign(create, { type: raw.type, match: raw.match });
236
- }
237
- var openOverlay = withMatcher(
238
- (payload) => overlaysSlice.actions.openOverlay(rawOpenPayload(payload)),
239
- overlaysSlice.actions.openOverlay
240
- );
241
- var closeOverlay = withMatcher(
242
- (payload) => overlaysSlice.actions.closeOverlay(
243
- payload.instanceId === void 0 ? { overlayId: payload.overlayId } : { overlayId: payload.overlayId, instanceId: payload.instanceId }
244
- ),
245
- overlaysSlice.actions.closeOverlay
246
- );
247
- var toggleOverlay = withMatcher(
248
- (payload) => overlaysSlice.actions.toggleOverlay(rawOpenPayload(payload)),
249
- overlaysSlice.actions.toggleOverlay
250
- );
251
- var closeAllInstancesOfOverlay = withMatcher(
252
- (payload) => overlaysSlice.actions.closeAllInstancesOfOverlay({ overlayId: payload.overlayId }),
253
- overlaysSlice.actions.closeAllInstancesOfOverlay
254
- );
255
- function overlayIdsBoundToPage() {
256
- return allOverlayMeta().filter((meta) => meta.closesOnNavigation === true).map((meta) => meta.id);
257
- }
258
- var closeOverlaysBoundToPage = withMatcher(
259
- (payload) => overlaysSlice.actions.closeOverlaysBoundToPage({
260
- overlayIds: [...payload?.overlayIds ?? overlayIdsBoundToPage()]
261
- }),
262
- overlaysSlice.actions.closeOverlaysBoundToPage
263
- );
264
- var { closeAllOverlays, pruneStaleInstances } = overlaysSlice.actions;
265
- var CLOSED_OVERLAY_INSTANCE = Object.freeze({ isOpen: false, data: null });
266
- var EMPTY_INSTANCES = Object.freeze([]);
267
- var selectOverlay = (state2, overlayId, instanceId = DEFAULT_INSTANCE_ID) => state2.overlays.overlays[overlayId]?.[instanceId] ?? CLOSED_OVERLAY_INSTANCE;
268
- var selectIsOverlayOpen = (state2, overlayId, instanceId = DEFAULT_INSTANCE_ID) => selectOverlay(state2, overlayId, instanceId).isOpen;
269
- var selectOverlayData = (state2, overlayId, instanceId = DEFAULT_INSTANCE_ID) => selectOverlay(state2, overlayId, instanceId).data;
270
- var openInstancesCache = () => globalSlot2("ai-matrx.summon.openInstancesSelectors", () => /* @__PURE__ */ new Map());
271
- var selectOpenInstances = (state2, overlayId) => {
272
- const cache = openInstancesCache();
273
- let selector = cache.get(overlayId);
274
- if (!selector) {
275
- selector = createSelector(
276
- (s) => s.overlays.overlays[overlayId],
277
- (instances) => {
278
- if (!instances) return EMPTY_INSTANCES;
279
- const result = [];
280
- for (const [instanceId, inst] of Object.entries(instances)) {
281
- if (inst.isOpen) result.push({ instanceId, data: inst.data });
282
- }
283
- return result.length === 0 ? EMPTY_INSTANCES : result;
284
- }
285
- );
286
- cache.set(overlayId, selector);
287
- }
288
- return selector(state2);
289
- };
290
- function listOpenInstanceKeys(state2) {
291
- const keys = [];
292
- for (const [overlayId, bucket] of Object.entries(state2.overlays.overlays)) {
293
- for (const [instanceId, inst] of Object.entries(bucket)) {
294
- if (inst.isOpen) keys.push(`${overlayId}:${instanceId}`);
295
- }
296
- }
297
- return keys;
298
- }
305
+ var { closeAllOverlays: closeAllOverlays2, pruneStaleInstances: pruneStaleInstances2 } = overlaysSlice.actions;
299
306
 
300
307
  // src/core/windowManagerSlice.ts
301
308
  import {
302
- createSelector as createSelector2,
309
+ createSelector,
303
310
  createSlice as createSlice2
304
311
  } from "@reduxjs/toolkit";
305
312
 
@@ -601,11 +608,11 @@ function trayChipsPerRow(viewportWidth) {
601
608
  Math.floor((usable + TRAY_GAP_X) / (chipWidth + TRAY_GAP_X))
602
609
  );
603
610
  }
604
- function traySlotRect(slot, viewportWidth, viewportHeight, totalSlots = slot + 1) {
611
+ function traySlotRect(slot2, viewportWidth, viewportHeight, totalSlots = slot2 + 1) {
605
612
  const chipWidth = computeTrayChipWidth(viewportWidth);
606
613
  const chipHeight = computeTrayChipHeight(viewportWidth);
607
614
  const perRow = trayChipsPerRow(viewportWidth);
608
- const safeSlot = Math.max(0, Math.floor(slot));
615
+ const safeSlot = Math.max(0, Math.floor(slot2));
609
616
  const usableHeight = Math.max(1, viewportHeight - TRAY_MARGIN_B - 8);
610
617
  const fullRows = Math.max(
611
618
  1,
@@ -754,44 +761,44 @@ var windowManagerSlice = createSlice2({
754
761
  const { id, title, initial, initialState: initialState5, persistence, viewport } = action.payload;
755
762
  if (state2.windows[id]) return;
756
763
  const safeInitial = viewport ? clampRectToViewport(initial, viewport) : initial;
757
- const pending = persistence ? state2.pendingRestores[windowSessionKey(persistence.overlayId, persistence.instanceId)] : void 0;
758
- const pendingRenderRect = pending ? pending.state === "minimized" && pending.traySlot !== null && viewport ? traySlotRect(
759
- pending.traySlot,
764
+ const pending2 = persistence ? state2.pendingRestores[windowSessionKey(persistence.overlayId, persistence.instanceId)] : void 0;
765
+ const pendingRenderRect = pending2 ? pending2.state === "minimized" && pending2.traySlot !== null && viewport ? traySlotRect(
766
+ pending2.traySlot,
760
767
  viewport.width,
761
768
  viewport.height,
762
769
  state2.trayCount
763
- ) : viewport ? clampRectToViewport(pending.windowedRect, viewport) : pending.renderRect : void 0;
764
- const startsMinimized = !pending && initialState5 === "minimized" && viewport !== void 0;
770
+ ) : viewport ? clampRectToViewport(pending2.windowedRect, viewport) : pending2.renderRect : void 0;
771
+ const startsMinimized = !pending2 && initialState5 === "minimized" && viewport !== void 0;
765
772
  const initialTraySlot = startsMinimized ? state2.trayCount : null;
766
773
  state2.windows[id] = {
767
774
  id,
768
- title: title ?? pending?.title ?? id,
769
- state: pending?.state ?? (startsMinimized ? "minimized" : "windowed"),
775
+ title: title ?? pending2?.title ?? id,
776
+ state: pending2?.state ?? (startsMinimized ? "minimized" : "windowed"),
770
777
  windowed: pendingRenderRect ?? safeInitial,
771
- preMinimizedRect: pending?.state === "minimized" ? pending.windowedRect : startsMinimized ? safeInitial : null,
772
- zIndex: pending?.zIndex ?? state2.nextZIndex++,
773
- traySlot: pending?.state === "minimized" ? pending.traySlot : initialTraySlot,
778
+ preMinimizedRect: pending2?.state === "minimized" ? pending2.windowedRect : startsMinimized ? safeInitial : null,
779
+ zIndex: pending2?.zIndex ?? state2.nextZIndex++,
780
+ traySlot: pending2?.state === "minimized" ? pending2.traySlot : initialTraySlot,
774
781
  popoutMode: null,
775
782
  prePopoutRect: null,
776
783
  ...persistence ? {
777
784
  persistence: {
778
785
  ...persistence,
779
- data: { ...pending?.data ?? {}, ...persistence.data },
780
- sidebarOpen: pending?.sidebarOpen ?? persistence.sidebarOpen,
781
- sidebarSize: pending?.sidebarSize ?? persistence.sidebarSize,
786
+ data: { ...pending2?.data ?? {}, ...persistence.data },
787
+ sidebarOpen: pending2?.sidebarOpen ?? persistence.sidebarOpen,
788
+ sidebarSize: pending2?.sidebarSize ?? persistence.sidebarSize,
782
789
  closing: false
783
790
  }
784
791
  } : {}
785
792
  };
786
- if (pending?.state === "minimized" && pending.traySlot !== null) {
787
- state2.trayCount = Math.max(state2.trayCount, pending.traySlot + 1);
793
+ if (pending2?.state === "minimized" && pending2.traySlot !== null) {
794
+ state2.trayCount = Math.max(state2.trayCount, pending2.traySlot + 1);
788
795
  } else if (startsMinimized && viewport) {
789
796
  state2.trayCount += 1;
790
797
  state2.trayViewport = viewport;
791
798
  recomputeAllTrayRects(state2);
792
799
  }
793
- if (pending && pending.zIndex >= state2.nextZIndex) {
794
- state2.nextZIndex = pending.zIndex + 1;
800
+ if (pending2 && pending2.zIndex >= state2.nextZIndex) {
801
+ state2.nextZIndex = pending2.zIndex + 1;
795
802
  }
796
803
  if (state2.windowsHidden) state2.windowsHidden = false;
797
804
  },
@@ -854,14 +861,14 @@ var windowManagerSlice = createSlice2({
854
861
  delete state2.pendingRestores[action.payload];
855
862
  },
856
863
  discardPendingWindowSession(state2, action) {
857
- const pending = state2.pendingRestores[action.payload];
858
- if (pending?.traySlot !== null && pending?.traySlot !== void 0 && !hasMatchingLiveTrayReservation(
864
+ const pending2 = state2.pendingRestores[action.payload];
865
+ if (pending2?.traySlot !== null && pending2?.traySlot !== void 0 && !hasMatchingLiveTrayReservation(
859
866
  state2,
860
- pending.overlayId,
861
- pending.instanceId,
862
- pending.traySlot
867
+ pending2.overlayId,
868
+ pending2.instanceId,
869
+ pending2.traySlot
863
870
  )) {
864
- compactReservedTraySlot(state2, pending.traySlot, pending.renderRect);
871
+ compactReservedTraySlot(state2, pending2.traySlot, pending2.renderRect);
865
872
  }
866
873
  delete state2.pendingRestores[action.payload];
867
874
  },
@@ -884,15 +891,15 @@ var windowManagerSlice = createSlice2({
884
891
  action.payload.overlayId,
885
892
  action.payload.instanceId
886
893
  );
887
- const pending = state2.pendingRestores[key];
888
- const hasMatchingLiveReservation = pending ? hasMatchingLiveTrayReservation(
894
+ const pending2 = state2.pendingRestores[key];
895
+ const hasMatchingLiveReservation = pending2 ? hasMatchingLiveTrayReservation(
889
896
  state2,
890
897
  action.payload.overlayId,
891
898
  action.payload.instanceId,
892
- pending.traySlot
899
+ pending2.traySlot
893
900
  ) : false;
894
- if (!hasMatchingLiveReservation && pending?.traySlot !== null && pending?.traySlot !== void 0) {
895
- compactReservedTraySlot(state2, pending.traySlot, pending.renderRect);
901
+ if (!hasMatchingLiveReservation && pending2?.traySlot !== null && pending2?.traySlot !== void 0) {
902
+ compactReservedTraySlot(state2, pending2.traySlot, pending2.renderRect);
896
903
  }
897
904
  delete state2.pendingRestores[key];
898
905
  Object.values(state2.windows).forEach((entry) => {
@@ -928,16 +935,16 @@ var windowManagerSlice = createSlice2({
928
935
  unregisterWindow(state2, action) {
929
936
  const win = state2.windows[action.payload];
930
937
  if (!win) return;
931
- const pending = win.persistence ? state2.pendingRestores[windowSessionKey(
938
+ const pending2 = win.persistence ? state2.pendingRestores[windowSessionKey(
932
939
  win.persistence.overlayId,
933
940
  win.persistence.instanceId
934
941
  )] : void 0;
935
942
  const pendingOwnsLiveReservation = Boolean(
936
- win.persistence && pending && hasMatchingLiveTrayReservation(
943
+ win.persistence && pending2 && hasMatchingLiveTrayReservation(
937
944
  state2,
938
945
  win.persistence.overlayId,
939
946
  win.persistence.instanceId,
940
- pending.traySlot
947
+ pending2.traySlot
941
948
  )
942
949
  );
943
950
  if (!pendingOwnsLiveReservation) releaseTraySlot(state2, win);
@@ -1031,8 +1038,8 @@ var windowManagerSlice = createSlice2({
1031
1038
  if (!win || win.state === "minimized") return;
1032
1039
  if (win.popoutMode !== null) return;
1033
1040
  win.preMinimizedRect = { ...win.windowed };
1034
- const slot = state2.trayCount;
1035
- win.traySlot = slot;
1041
+ const slot2 = state2.trayCount;
1042
+ win.traySlot = slot2;
1036
1043
  state2.trayCount += 1;
1037
1044
  state2.trayViewport = { width: viewportWidth, height: viewportHeight };
1038
1045
  win.state = "minimized";
@@ -1049,8 +1056,8 @@ var windowManagerSlice = createSlice2({
1049
1056
  if (win.state !== "windowed") return;
1050
1057
  if (win.popoutMode !== null) return;
1051
1058
  win.preMinimizedRect = { ...win.windowed };
1052
- const slot = state2.trayCount;
1053
- win.traySlot = slot;
1059
+ const slot2 = state2.trayCount;
1060
+ win.traySlot = slot2;
1054
1061
  state2.trayCount += 1;
1055
1062
  win.state = "minimized";
1056
1063
  });
@@ -1346,19 +1353,19 @@ var windowManagerSlice = createSlice2({
1346
1353
  if (typeof overlayId !== "string" || typeof instanceId !== "string") {
1347
1354
  return;
1348
1355
  }
1349
- const pending = Object.values(state2.pendingRestores).find(
1356
+ const pending2 = Object.values(state2.pendingRestores).find(
1350
1357
  (session) => session.overlayId === overlayId && session.instanceId === instanceId
1351
1358
  );
1352
- const hasMatchingLive = pending ? hasMatchingLiveTrayReservation(
1359
+ const hasMatchingLive = pending2 ? hasMatchingLiveTrayReservation(
1353
1360
  state2,
1354
1361
  overlayId,
1355
1362
  instanceId,
1356
- pending.traySlot
1363
+ pending2.traySlot
1357
1364
  ) : false;
1358
- if (!hasMatchingLive && pending?.traySlot != null) {
1359
- compactReservedTraySlot(state2, pending.traySlot, pending.renderRect);
1365
+ if (!hasMatchingLive && pending2?.traySlot != null) {
1366
+ compactReservedTraySlot(state2, pending2.traySlot, pending2.renderRect);
1360
1367
  }
1361
- if (pending) delete state2.pendingRestores[pending.sessionKey];
1368
+ if (pending2) delete state2.pendingRestores[pending2.sessionKey];
1362
1369
  Object.values(state2.windows).forEach((entry) => {
1363
1370
  if (entry.persistence?.overlayId === overlayId && entry.persistence.instanceId === instanceId) {
1364
1371
  entry.persistence.closing = true;
@@ -1431,17 +1438,17 @@ var {
1431
1438
  releaseTransientWindow,
1432
1439
  registerWindow,
1433
1440
  unregisterWindow,
1434
- focusWindow,
1435
- restoreWindow,
1441
+ focusWindow: focusWindow2,
1442
+ restoreWindow: restoreWindow2,
1436
1443
  revealWindow,
1437
1444
  maximizeWindow,
1438
1445
  minimizeWindow,
1439
- minimizeAll,
1440
- restoreAll,
1446
+ minimizeAll: minimizeAll2,
1447
+ restoreAll: restoreAll2,
1441
1448
  recomputeTrayPositions,
1442
1449
  updateWindowRect,
1443
1450
  updateWindowTitle,
1444
- toggleWindowsHidden,
1451
+ toggleWindowsHidden: toggleWindowsHidden2,
1445
1452
  moveTraySlot,
1446
1453
  arrangeActiveWindows,
1447
1454
  popOutWindow,
@@ -1468,15 +1475,15 @@ var selectTransientZIndex = (id) => (state2) => state2.windowManager.transientZ[
1468
1475
  var selectWindowTitle = (id) => (state2) => state2.windowManager.windows[id]?.title ?? id;
1469
1476
  var selectTraySlotWidth = () => TRAY_SLOT_WIDTH;
1470
1477
  var selectWindowsHidden = (state2) => state2.windowManager.windowsHidden;
1471
- var selectTrayWindows = createSelector2(
1478
+ var selectTrayWindows = createSelector(
1472
1479
  [selectWindowsMap],
1473
1480
  (windows) => Object.values(windows).filter((w) => w.state === "minimized").sort((a, b) => (a.traySlot ?? 0) - (b.traySlot ?? 0))
1474
1481
  );
1475
- var selectAllWindows = createSelector2(
1482
+ var selectAllWindows = createSelector(
1476
1483
  [selectWindowsMap],
1477
1484
  (windows) => Object.values(windows).sort((a, b) => b.zIndex - a.zIndex)
1478
1485
  );
1479
- var selectAllMinimized = createSelector2(
1486
+ var selectAllMinimized = createSelector(
1480
1487
  [selectWindowsMap],
1481
1488
  (windows) => {
1482
1489
  const wins = Object.values(windows);
@@ -1488,7 +1495,7 @@ var selectIsPoppedOut = (id) => (state2) => (state2.windowManager.windows[id]?.p
1488
1495
  var selectActivePipWindowId = (state2) => state2.windowManager.activePipWindowId;
1489
1496
  var selectPopoutCandidateId = (state2) => state2.windowManager.popoutCandidateId;
1490
1497
  var selectPrePopoutRect = (id) => (state2) => state2.windowManager.windows[id]?.prePopoutRect ?? null;
1491
- var selectDockedWindows = createSelector2(
1498
+ var selectDockedWindows = createSelector(
1492
1499
  [selectWindowsMap],
1493
1500
  (windows) => Object.values(windows).filter((w) => w.popoutMode === null).sort((a, b) => b.zIndex - a.zIndex)
1494
1501
  );
@@ -1560,7 +1567,7 @@ var selectOverlayStateFor = (state2, key) => state2.overlayState.entries[key]?.v
1560
1567
  import { combineReducers, configureStore } from "@reduxjs/toolkit";
1561
1568
 
1562
1569
  // src/core/middleware/closeLifecycle.ts
1563
- import { globalSlot as globalSlot4 } from "@ai-matrx/kit/global-slot";
1570
+ import { globalSlot as globalSlot5 } from "@ai-matrx/kit/global-slot";
1564
1571
 
1565
1572
  // src/handles/callbackManager.ts
1566
1573
  import { globalSlot as globalSlot3 } from "@ai-matrx/kit/global-slot";
@@ -1589,9 +1596,9 @@ var handlesState = () => globalSlot3(HANDLES_SLOT, () => ({
1589
1596
  owners: /* @__PURE__ */ new Map(),
1590
1597
  registryListeners: /* @__PURE__ */ new Set()
1591
1598
  }));
1592
- function invoke(slot, data, context) {
1593
- if (typeof slot !== "function") return void 0;
1594
- return slot(data, context);
1599
+ function invoke(slot2, data, context) {
1600
+ if (typeof slot2 !== "function") return void 0;
1601
+ return slot2(data, context);
1595
1602
  }
1596
1603
  function invokeListener(listener, data, context) {
1597
1604
  return listener(data, context);
@@ -1623,11 +1630,11 @@ var CallbackManager = class {
1623
1630
  return this.registerEntry(callback, options);
1624
1631
  }
1625
1632
  /** @internal The one insertion path (typed helpers pass a fixed id and a removal hook). */
1626
- registerEntry(slot, options) {
1633
+ registerEntry(slot2, options) {
1627
1634
  const s = this.s;
1628
1635
  const callbackId = options.id ?? newHandleId();
1629
1636
  if (s.callbacks.has(callbackId)) this.deleteEntry(callbackId, false);
1630
- const entry = { callback: slot };
1637
+ const entry = { callback: slot2 };
1631
1638
  if (options.context !== void 0) entry.context = options.context;
1632
1639
  if (options.groupId !== void 0) entry.groupId = options.groupId;
1633
1640
  if (options.owner !== void 0) entry.owner = options.owner;
@@ -1817,8 +1824,16 @@ var CallbackManager = class {
1817
1824
  };
1818
1825
  var callbackManager = new CallbackManager();
1819
1826
 
1827
+ // src/open/channels.ts
1828
+ import { globalSlot as globalSlot4 } from "@ai-matrx/kit/global-slot";
1829
+ var pending = () => globalSlot4("ai-matrx.summon.pendingChannels", () => /* @__PURE__ */ new Map());
1830
+ function dropPendingChannelsOf(owner) {
1831
+ const map = pending();
1832
+ for (const [id, entry] of [...map]) if (entry.owner === owner) map.delete(id);
1833
+ }
1834
+
1820
1835
  // src/core/middleware/closeLifecycle.ts
1821
- var closeState = () => globalSlot4("ai-matrx.summon.closeLifecycle", () => ({ flushers: /* @__PURE__ */ new Set() }));
1836
+ var closeState = () => globalSlot5("ai-matrx.summon.closeLifecycle", () => ({ flushers: /* @__PURE__ */ new Set() }));
1822
1837
  function registerCloseFlusher(flush) {
1823
1838
  const { flushers } = closeState();
1824
1839
  flushers.add(flush);
@@ -1844,7 +1859,7 @@ function preservedIdentities(state2, overlayId) {
1844
1859
  }
1845
1860
  return identities;
1846
1861
  }
1847
- function isPlainRecord2(value) {
1862
+ function isPlainRecord3(value) {
1848
1863
  return typeof value === "object" && value !== null && !Array.isArray(value);
1849
1864
  }
1850
1865
  var CLOSE_TYPES = /* @__PURE__ */ new Set([
@@ -1856,6 +1871,7 @@ var CLOSE_TYPES = /* @__PURE__ */ new Set([
1856
1871
  ]);
1857
1872
  function releaseOverlayInstance(dispatch, key, options = {}) {
1858
1873
  callbackManager.disposeOwner(key);
1874
+ dropPendingChannelsOf(key);
1859
1875
  if (!options.keepState) dispatch(clearOverlayState({ key }));
1860
1876
  }
1861
1877
  function closeInstanceResources(api, key) {
@@ -1864,14 +1880,15 @@ function closeInstanceResources(api, key) {
1864
1880
  if (keepAlive === "hidden") return;
1865
1881
  const hasState = api.getState().overlayState?.entries[key] !== void 0;
1866
1882
  callbackManager.disposeOwner(key);
1883
+ dropPendingChannelsOf(key);
1867
1884
  if (keepAlive !== "restore" && hasState) api.dispatch(clearOverlayState({ key }));
1868
1885
  }
1869
1886
  var closeLifecycleMiddleware = (api) => (next) => (action) => {
1870
- if (!isPlainRecord2(action) || typeof action.type !== "string" || !CLOSE_TYPES.has(action.type)) {
1887
+ if (!isPlainRecord3(action) || typeof action.type !== "string" || !CLOSE_TYPES.has(action.type)) {
1871
1888
  return next(action);
1872
1889
  }
1873
1890
  const type = action.type;
1874
- const payload = isPlainRecord2(action.payload) ? action.payload : null;
1891
+ const payload = isPlainRecord3(action.payload) ? action.payload : null;
1875
1892
  const before = api.getState();
1876
1893
  const openBefore = new Set(listOpenInstanceKeys(before));
1877
1894
  let closing = [];
@@ -1885,7 +1902,7 @@ var closeLifecycleMiddleware = (api) => (next) => (action) => {
1885
1902
  intents.push({ scope: "overlay", overlayId });
1886
1903
  } else if ((type === overlaysRawActions.closeOverlay.type || type === overlaysRawActions.toggleOverlay.type) && overlayId) {
1887
1904
  const instanceId = typeof payload?.instanceId === "string" ? payload.instanceId : DEFAULT_INSTANCE_ID;
1888
- const wasOpen = before.overlays.overlays[overlayId]?.[instanceId]?.isOpen === true;
1905
+ const wasOpen = before.overlays?.overlays[overlayId]?.[instanceId]?.isOpen === true;
1889
1906
  if (type === overlaysRawActions.closeOverlay.type || wasOpen) {
1890
1907
  closing = [{ overlayId, instanceId }];
1891
1908
  intents.push({ scope: "exact", overlayId, instanceId });
@@ -1917,12 +1934,12 @@ var closeLifecycleMiddleware = (api) => (next) => (action) => {
1917
1934
  };
1918
1935
 
1919
1936
  // src/core/middleware/renderWatchdog.ts
1920
- import { globalSlot as globalSlot5 } from "@ai-matrx/kit/global-slot";
1937
+ import { globalSlot as globalSlot6 } from "@ai-matrx/kit/global-slot";
1921
1938
  var LAZY_WINDOW_MOUNT_DEADLINE_MS = process.env.NODE_ENV === "production" ? 12e3 : 45e3;
1922
1939
  var OPEN_TYPE = "overlays/openOverlay";
1923
1940
  var TOGGLE_TYPE = "overlays/toggleOverlay";
1924
1941
  var DEFAULT_INSTANCE_ID2 = "default";
1925
- function isPlainRecord3(value) {
1942
+ function isPlainRecord4(value) {
1926
1943
  return typeof value === "object" && value !== null && !Array.isArray(value);
1927
1944
  }
1928
1945
  var CHECK_DELAY_MS = 2500;
@@ -1932,7 +1949,7 @@ var NO_MOUNT_DEADLINE_MS = LAZY_WINDOW_MOUNT_DEADLINE_MS;
1932
1949
  var TOAST_DURATION_MS = 8e3;
1933
1950
  var RECOVERY_POLL_MS = 500;
1934
1951
  var RENDER_WATCHDOG_SLOT = "ai-matrx.summon.renderWatchdog";
1935
- var watchdogState = () => globalSlot5(RENDER_WATCHDOG_SLOT, () => ({
1952
+ var watchdogState = () => globalSlot6(RENDER_WATCHDOG_SLOT, () => ({
1936
1953
  renderAcks: /* @__PURE__ */ new Map(),
1937
1954
  ackWaiters: /* @__PURE__ */ new Map(),
1938
1955
  watches: /* @__PURE__ */ new Map()
@@ -2149,9 +2166,9 @@ function createOverlayRenderWatchdogMiddleware(ports) {
2149
2166
  const typed = action;
2150
2167
  if (typed.type !== OPEN_TYPE && typed.type !== TOGGLE_TYPE) return result;
2151
2168
  const payload = typed.payload;
2152
- const overlayId = isPlainRecord3(payload) && typeof payload.overlayId === "string" ? payload.overlayId : void 0;
2169
+ const overlayId = isPlainRecord4(payload) && typeof payload.overlayId === "string" ? payload.overlayId : void 0;
2153
2170
  if (!overlayId) return result;
2154
- const instanceIdRaw = isPlainRecord3(payload) && typeof payload.instanceId === "string" ? payload.instanceId : void 0;
2171
+ const instanceIdRaw = isPlainRecord4(payload) && typeof payload.instanceId === "string" ? payload.instanceId : void 0;
2155
2172
  const meta = getOverlayMeta(overlayId);
2156
2173
  if (!meta || !watchdogTracksOpen(meta, instanceIdRaw ?? DEFAULT_INSTANCE_ID2)) {
2157
2174
  return result;
@@ -2209,6 +2226,23 @@ function buildDockWindowPayload(windowId) {
2209
2226
  viewportHeight: window.innerHeight
2210
2227
  };
2211
2228
  }
2229
+
2230
+ // src/open/gate.ts
2231
+ import { globalSlot as globalSlot7 } from "@ai-matrx/kit/global-slot";
2232
+ var slot = () => globalSlot7("ai-matrx.summon.gate", () => ({ core: null, loading: null, gates: /* @__PURE__ */ new Set(), listeners: /* @__PURE__ */ new Set() }));
2233
+ function installSummonCore(core) {
2234
+ const s = slot();
2235
+ if (s.core) return;
2236
+ s.core = core;
2237
+ const gates = [...s.gates];
2238
+ s.gates.clear();
2239
+ for (const gate of gates) gate.install(core);
2240
+ for (const listener of [...s.listeners]) listener();
2241
+ }
2242
+
2243
+ // src/index.ts
2244
+ var summonCore = { reducers: summonReducers, createMiddleware: createSummonMiddleware };
2245
+ installSummonCore(summonCore);
2212
2246
  export {
2213
2247
  DEFAULT_INSTANCE_ID,
2214
2248
  DEFAULT_PORTS,
@@ -2245,7 +2279,7 @@ export {
2245
2279
  clearOverlaySurfaceRender,
2246
2280
  clearWindowPersistenceState,
2247
2281
  closeAllInstancesOfOverlay,
2248
- closeAllOverlays,
2282
+ closeAllOverlays2 as closeAllOverlays,
2249
2283
  closeLifecycleMiddleware,
2250
2284
  closeOverlay,
2251
2285
  closeOverlaysBoundToPage,
@@ -2263,7 +2297,7 @@ export {
2263
2297
  diagnoseOverlayRender,
2264
2298
  discardPendingWindowSession,
2265
2299
  dockWindow,
2266
- focusWindow,
2300
+ focusWindow2 as focusWindow,
2267
2301
  getGrid12Rect,
2268
2302
  getGrid4Rect,
2269
2303
  getGrid6Rect,
@@ -2288,7 +2322,7 @@ export {
2288
2322
  locationRouter,
2289
2323
  markWindowClosing,
2290
2324
  maximizeWindow,
2291
- minimizeAll,
2325
+ minimizeAll2 as minimizeAll,
2292
2326
  minimizeWindow,
2293
2327
  moveTraySlot,
2294
2328
  openOverlay,
@@ -2298,7 +2332,7 @@ export {
2298
2332
  overlaysReducer,
2299
2333
  parseInstanceKey,
2300
2334
  popOutWindow,
2301
- pruneStaleInstances,
2335
+ pruneStaleInstances2 as pruneStaleInstances,
2302
2336
  raiseTransientWindow,
2303
2337
  recomputeTrayPositions,
2304
2338
  rectOnScreen,
@@ -2313,8 +2347,8 @@ export {
2313
2347
  resetOverlayRegistry,
2314
2348
  resetOverlayRenderWatchdog,
2315
2349
  resolvePorts,
2316
- restoreAll,
2317
- restoreWindow,
2350
+ restoreAll2 as restoreAll,
2351
+ restoreWindow2 as restoreWindow,
2318
2352
  restoreWindowState,
2319
2353
  revealWindow,
2320
2354
  safeViewportDims,
@@ -2349,9 +2383,10 @@ export {
2349
2383
  setOverlayStateValue,
2350
2384
  setPopoutCandidate,
2351
2385
  subscribeToOverlayRegistry,
2386
+ summonCore,
2352
2387
  summonReducers,
2353
2388
  toggleOverlay,
2354
- toggleWindowsHidden,
2389
+ toggleWindowsHidden2 as toggleWindowsHidden,
2355
2390
  trayChipsPerRow,
2356
2391
  traySlotRect,
2357
2392
  unregisterSyncEntry,