@ai-matrx/summon 0.1.6 → 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.
- package/CHANGELOG.md +21 -2
- package/dist/gate-DUvE-Cc1.d.cts +399 -0
- package/dist/gate-DUvE-Cc1.d.ts +399 -0
- package/dist/handles.cjs +1 -0
- package/dist/handles.cjs.map +1 -1
- package/dist/handles.d.cts +3 -61
- package/dist/handles.d.ts +3 -61
- package/dist/handles.js +1 -0
- package/dist/handles.js.map +1 -1
- package/dist/helpers-2NY1ha0V.d.cts +63 -0
- package/dist/helpers-2NY1ha0V.d.ts +63 -0
- package/dist/index.cjs +194 -159
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +9 -355
- package/dist/index.d.ts +9 -355
- package/dist/index.js +200 -165
- package/dist/index.js.map +1 -1
- package/dist/instanceBody-CgZAFnic.d.cts +23 -0
- package/dist/instanceBody-CgZAFnic.d.ts +23 -0
- package/dist/open.cjs +408 -0
- package/dist/open.cjs.map +1 -0
- package/dist/open.d.cts +22 -0
- package/dist/open.d.ts +22 -0
- package/dist/open.js +375 -0
- package/dist/open.js.map +1 -0
- package/dist/persistence.cjs +27 -2
- package/dist/persistence.cjs.map +1 -1
- package/dist/persistence.js +28 -3
- package/dist/persistence.js.map +1 -1
- package/dist/react.cjs +249 -352
- package/dist/react.cjs.map +1 -1
- package/dist/react.d.cts +11 -151
- package/dist/react.d.ts +11 -151
- package/dist/react.js +210 -306
- package/dist/react.js.map +1 -1
- package/dist/root.cjs +277 -0
- package/dist/root.cjs.map +1 -0
- package/dist/root.d.cts +175 -0
- package/dist/root.d.ts +175 -0
- package/dist/root.js +254 -0
- package/dist/root.js.map +1 -0
- package/dist/window-host.cjs +11 -2
- package/dist/window-host.cjs.map +1 -1
- package/dist/window-host.d.cts +1 -0
- package/dist/window-host.d.ts +1 -0
- package/dist/window-host.js +11 -2
- package/dist/window-host.js.map +1 -1
- package/dist/window.cjs +2 -1
- package/dist/window.cjs.map +1 -1
- package/dist/window.d.cts +3 -2
- package/dist/window.d.ts +3 -2
- package/dist/window.js +2 -1
- package/dist/window.js.map +1 -1
- package/package.json +26 -3
package/dist/react.js
CHANGED
|
@@ -8,10 +8,7 @@ import { createSummonStore } from "@ai-matrx/summon";
|
|
|
8
8
|
|
|
9
9
|
// src/react/context.ts
|
|
10
10
|
import { createContext } from "react";
|
|
11
|
-
|
|
12
|
-
SummonStoreContext.displayName = "SummonStoreContext";
|
|
13
|
-
var SummonPortsContext = createContext(null);
|
|
14
|
-
SummonPortsContext.displayName = "SummonPortsContext";
|
|
11
|
+
import { SummonStoreContext, SummonPortsContext } from "@ai-matrx/summon/root";
|
|
15
12
|
var SummonConfigContext = createContext(null);
|
|
16
13
|
SummonConfigContext.displayName = "SummonConfigContext";
|
|
17
14
|
|
|
@@ -21,114 +18,8 @@ import { Button } from "@ai-matrx/design-system";
|
|
|
21
18
|
|
|
22
19
|
// src/react/storeHooks.ts
|
|
23
20
|
import { useContext } from "react";
|
|
24
|
-
import {
|
|
25
|
-
|
|
26
|
-
createSelectorHook,
|
|
27
|
-
createStoreHook
|
|
28
|
-
} from "react-redux";
|
|
29
|
-
import { DEFAULT_PORTS } from "@ai-matrx/summon";
|
|
30
|
-
var useSummonSelector = createSelectorHook(SummonStoreContext).withTypes();
|
|
31
|
-
var useSummonDispatch = createDispatchHook(SummonStoreContext).withTypes();
|
|
32
|
-
var useSummonStore = createStoreHook(SummonStoreContext).withTypes();
|
|
33
|
-
var MISSING_PROVIDER = "[summon] No <SummonProvider> above this component. Wrap the app (or the part that opens overlays) in <SummonProvider>.";
|
|
34
|
-
function useSummonPorts() {
|
|
35
|
-
const ports = useContext(SummonPortsContext);
|
|
36
|
-
if (!ports) throw new Error(MISSING_PROVIDER);
|
|
37
|
-
return ports;
|
|
38
|
-
}
|
|
39
|
-
function useOptionalSummonPorts() {
|
|
40
|
-
return useContext(SummonPortsContext) ?? DEFAULT_PORTS;
|
|
41
|
-
}
|
|
42
|
-
function useOptionalSummonStore() {
|
|
43
|
-
const context = useContext(SummonStoreContext);
|
|
44
|
-
return context ? context.store : null;
|
|
45
|
-
}
|
|
46
|
-
function useSummonConfig() {
|
|
47
|
-
const config = useContext(SummonConfigContext);
|
|
48
|
-
if (!config) throw new Error(MISSING_PROVIDER);
|
|
49
|
-
return config;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
// src/react/fallbacks.tsx
|
|
53
|
-
import { jsx, jsxs } from "react/jsx-runtime";
|
|
54
|
-
function normalizeOverlayError(error) {
|
|
55
|
-
if (error instanceof Error) {
|
|
56
|
-
const isChunkLoadError = error.name === "ChunkLoadError" || /Loading chunk [\w-]+ failed|Failed to fetch dynamically imported module|Importing a module script failed/i.test(
|
|
57
|
-
error.message
|
|
58
|
-
);
|
|
59
|
-
return { name: error.name, message: error.message, stack: error.stack ?? null, isChunkLoadError };
|
|
60
|
-
}
|
|
61
|
-
return { name: "Error", message: typeof error === "string" ? error : String(error), stack: null, isChunkLoadError: false };
|
|
62
|
-
}
|
|
63
|
-
function OverlayLoadingFallback({ overlayId, label }) {
|
|
64
|
-
const ports = useSummonPorts();
|
|
65
|
-
const { stallWarnMs } = useSummonConfig();
|
|
66
|
-
useEffect(() => {
|
|
67
|
-
const timer = setTimeout(() => {
|
|
68
|
-
ports.errors.capture(new Error(`Overlay "${overlayId}" still loading after ${stallWarnMs}ms`), {
|
|
69
|
-
stage: "overlay-load-stall",
|
|
70
|
-
overlayId,
|
|
71
|
-
level: "warning"
|
|
72
|
-
});
|
|
73
|
-
}, stallWarnMs);
|
|
74
|
-
return () => clearTimeout(timer);
|
|
75
|
-
}, [ports, overlayId, stallWarnMs]);
|
|
76
|
-
return /* @__PURE__ */ jsx("div", { className: "pointer-events-none fixed inset-0 z-[2147483000] flex items-center justify-center p-4", children: /* @__PURE__ */ jsxs(
|
|
77
|
-
"div",
|
|
78
|
-
{
|
|
79
|
-
role: "status",
|
|
80
|
-
"aria-label": `Loading ${label}`,
|
|
81
|
-
className: "pointer-events-auto flex items-center gap-3 rounded-xl border border-border bg-card px-5 py-4 text-sm text-muted-foreground shadow-[var(--elevation-2)]",
|
|
82
|
-
children: [
|
|
83
|
-
/* @__PURE__ */ jsx("span", { "aria-hidden": true, className: "size-4 animate-spin rounded-full border-2 border-border border-t-primary" }),
|
|
84
|
-
/* @__PURE__ */ jsx("span", { children: "Loading\u2026" })
|
|
85
|
-
]
|
|
86
|
-
}
|
|
87
|
-
) });
|
|
88
|
-
}
|
|
89
|
-
function OverlayErrorFallback({ label, error, retry, close, extras }) {
|
|
90
|
-
const e = normalizeOverlayError(error);
|
|
91
|
-
return /* @__PURE__ */ jsx("div", { className: "pointer-events-none fixed inset-0 z-[2147483001] flex items-center justify-center p-4", children: /* @__PURE__ */ jsxs(
|
|
92
|
-
"div",
|
|
93
|
-
{
|
|
94
|
-
role: "alertdialog",
|
|
95
|
-
"aria-label": `${label} failed to load`,
|
|
96
|
-
className: "pointer-events-auto flex max-h-[85dvh] w-full max-w-lg flex-col overflow-hidden rounded-xl border border-destructive bg-card shadow-[var(--elevation-3)]",
|
|
97
|
-
children: [
|
|
98
|
-
/* @__PURE__ */ jsxs("div", { className: "border-b border-border px-5 py-4", children: [
|
|
99
|
-
/* @__PURE__ */ jsxs("h2", { className: "text-sm font-semibold text-foreground", children: [
|
|
100
|
-
label,
|
|
101
|
-
" failed to load"
|
|
102
|
-
] }),
|
|
103
|
-
/* @__PURE__ */ jsx("p", { className: "mt-1 text-xs text-muted-foreground", children: e.isChunkLoadError ? "Part of it did not finish loading." : "It hit an error while rendering." })
|
|
104
|
-
] }),
|
|
105
|
-
/* @__PURE__ */ jsx("div", { className: "min-h-0 flex-1 overflow-auto px-5 py-4", children: /* @__PURE__ */ jsxs("div", { className: "rounded-lg bg-muted px-3 py-2 font-mono text-xs text-foreground", children: [
|
|
106
|
-
/* @__PURE__ */ jsx("span", { className: "text-destructive", children: e.name }),
|
|
107
|
-
": ",
|
|
108
|
-
e.message
|
|
109
|
-
] }) }),
|
|
110
|
-
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-2 border-t border-border px-5 py-3", children: [
|
|
111
|
-
/* @__PURE__ */ jsx("div", { children: extras }),
|
|
112
|
-
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
113
|
-
/* @__PURE__ */ jsx(Button, { variant: "ghost", size: "sm", onClick: close, children: "Close" }),
|
|
114
|
-
/* @__PURE__ */ jsx(Button, { variant: "primary", size: "sm", onClick: retry, children: "Try again" }),
|
|
115
|
-
/* @__PURE__ */ jsx(
|
|
116
|
-
Button,
|
|
117
|
-
{
|
|
118
|
-
variant: "outline",
|
|
119
|
-
size: "sm",
|
|
120
|
-
onClick: () => {
|
|
121
|
-
if (typeof window !== "undefined") window.location.reload();
|
|
122
|
-
},
|
|
123
|
-
children: "Reload page"
|
|
124
|
-
}
|
|
125
|
-
)
|
|
126
|
-
] })
|
|
127
|
-
] })
|
|
128
|
-
]
|
|
129
|
-
}
|
|
130
|
-
) });
|
|
131
|
-
}
|
|
21
|
+
import { getSummonHostConfig, getSummonHostVersion } from "@ai-matrx/summon/root";
|
|
22
|
+
import { globalSlot } from "@ai-matrx/kit/global-slot";
|
|
132
23
|
|
|
133
24
|
// src/react/keepAlive.ts
|
|
134
25
|
var KeepAliveRegistry = class {
|
|
@@ -221,11 +112,126 @@ var LoaderCache = class {
|
|
|
221
112
|
}
|
|
222
113
|
};
|
|
223
114
|
|
|
224
|
-
// src/react/
|
|
225
|
-
import {
|
|
115
|
+
// src/react/storeHooks.ts
|
|
116
|
+
import {
|
|
117
|
+
useSummonSelector,
|
|
118
|
+
useSummonDispatch,
|
|
119
|
+
useSummonStore,
|
|
120
|
+
useSummonPorts,
|
|
121
|
+
useOptionalSummonPorts,
|
|
122
|
+
useOptionalSummonStore
|
|
123
|
+
} from "@ai-matrx/summon/root";
|
|
226
124
|
var DEFAULT_KEEP_ALIVE_LIMIT = 8;
|
|
227
125
|
var DEFAULT_IMPORT_TIMEOUT_MS = 12e3;
|
|
228
126
|
var DEFAULT_STALL_WARN_MS = 1e4;
|
|
127
|
+
var hostConfigSlot = () => globalSlot("ai-matrx.summon.hostReactConfig", () => ({ version: -1, config: null, keepAlive: null, loaders: null }));
|
|
128
|
+
function hostReactConfig() {
|
|
129
|
+
const s = hostConfigSlot();
|
|
130
|
+
const version = getSummonHostVersion();
|
|
131
|
+
if (s.config && s.version === version) return s.config;
|
|
132
|
+
const host = getSummonHostConfig();
|
|
133
|
+
s.keepAlive ??= new KeepAliveRegistry(DEFAULT_KEEP_ALIVE_LIMIT);
|
|
134
|
+
s.loaders ??= new LoaderCache({ timeoutMs: () => DEFAULT_IMPORT_TIMEOUT_MS });
|
|
135
|
+
s.config = {
|
|
136
|
+
loadingFallback: OverlayLoadingFallback,
|
|
137
|
+
errorFallback: OverlayErrorFallback,
|
|
138
|
+
errorReportExtras: host.errorReportExtras ?? null,
|
|
139
|
+
renderWrapper: host.renderWrapper ?? null,
|
|
140
|
+
importTimeoutMs: DEFAULT_IMPORT_TIMEOUT_MS,
|
|
141
|
+
stallWarnMs: DEFAULT_STALL_WARN_MS,
|
|
142
|
+
keepAlive: s.keepAlive,
|
|
143
|
+
loaders: s.loaders
|
|
144
|
+
};
|
|
145
|
+
s.version = version;
|
|
146
|
+
return s.config;
|
|
147
|
+
}
|
|
148
|
+
function useSummonConfig() {
|
|
149
|
+
return useContext(SummonConfigContext) ?? hostReactConfig();
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// src/react/fallbacks.tsx
|
|
153
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
154
|
+
function normalizeOverlayError(error) {
|
|
155
|
+
if (error instanceof Error) {
|
|
156
|
+
const isChunkLoadError = error.name === "ChunkLoadError" || /Loading chunk [\w-]+ failed|Failed to fetch dynamically imported module|Importing a module script failed/i.test(
|
|
157
|
+
error.message
|
|
158
|
+
);
|
|
159
|
+
return { name: error.name, message: error.message, stack: error.stack ?? null, isChunkLoadError };
|
|
160
|
+
}
|
|
161
|
+
return { name: "Error", message: typeof error === "string" ? error : String(error), stack: null, isChunkLoadError: false };
|
|
162
|
+
}
|
|
163
|
+
function OverlayLoadingFallback({ overlayId, label }) {
|
|
164
|
+
const ports = useSummonPorts();
|
|
165
|
+
const { stallWarnMs } = useSummonConfig();
|
|
166
|
+
useEffect(() => {
|
|
167
|
+
const timer = setTimeout(() => {
|
|
168
|
+
ports.errors.capture(new Error(`Overlay "${overlayId}" still loading after ${stallWarnMs}ms`), {
|
|
169
|
+
stage: "overlay-load-stall",
|
|
170
|
+
overlayId,
|
|
171
|
+
level: "warning"
|
|
172
|
+
});
|
|
173
|
+
}, stallWarnMs);
|
|
174
|
+
return () => clearTimeout(timer);
|
|
175
|
+
}, [ports, overlayId, stallWarnMs]);
|
|
176
|
+
return /* @__PURE__ */ jsx("div", { className: "pointer-events-none fixed inset-0 z-[2147483000] flex items-center justify-center p-4", children: /* @__PURE__ */ jsxs(
|
|
177
|
+
"div",
|
|
178
|
+
{
|
|
179
|
+
role: "status",
|
|
180
|
+
"aria-label": `Loading ${label}`,
|
|
181
|
+
className: "pointer-events-auto flex items-center gap-3 rounded-xl border border-border bg-card px-5 py-4 text-sm text-muted-foreground shadow-[var(--elevation-2)]",
|
|
182
|
+
children: [
|
|
183
|
+
/* @__PURE__ */ jsx("span", { "aria-hidden": true, className: "size-4 animate-spin rounded-full border-2 border-border border-t-primary" }),
|
|
184
|
+
/* @__PURE__ */ jsx("span", { children: "Loading\u2026" })
|
|
185
|
+
]
|
|
186
|
+
}
|
|
187
|
+
) });
|
|
188
|
+
}
|
|
189
|
+
function OverlayErrorFallback({ label, error, retry, close, extras }) {
|
|
190
|
+
const e = normalizeOverlayError(error);
|
|
191
|
+
return /* @__PURE__ */ jsx("div", { className: "pointer-events-none fixed inset-0 z-[2147483001] flex items-center justify-center p-4", children: /* @__PURE__ */ jsxs(
|
|
192
|
+
"div",
|
|
193
|
+
{
|
|
194
|
+
role: "alertdialog",
|
|
195
|
+
"aria-label": `${label} failed to load`,
|
|
196
|
+
className: "pointer-events-auto flex max-h-[85dvh] w-full max-w-lg flex-col overflow-hidden rounded-xl border border-destructive bg-card shadow-[var(--elevation-3)]",
|
|
197
|
+
children: [
|
|
198
|
+
/* @__PURE__ */ jsxs("div", { className: "border-b border-border px-5 py-4", children: [
|
|
199
|
+
/* @__PURE__ */ jsxs("h2", { className: "text-sm font-semibold text-foreground", children: [
|
|
200
|
+
label,
|
|
201
|
+
" failed to load"
|
|
202
|
+
] }),
|
|
203
|
+
/* @__PURE__ */ jsx("p", { className: "mt-1 text-xs text-muted-foreground", children: e.isChunkLoadError ? "Part of it did not finish loading." : "It hit an error while rendering." })
|
|
204
|
+
] }),
|
|
205
|
+
/* @__PURE__ */ jsx("div", { className: "min-h-0 flex-1 overflow-auto px-5 py-4", children: /* @__PURE__ */ jsxs("div", { className: "rounded-lg bg-muted px-3 py-2 font-mono text-xs text-foreground", children: [
|
|
206
|
+
/* @__PURE__ */ jsx("span", { className: "text-destructive", children: e.name }),
|
|
207
|
+
": ",
|
|
208
|
+
e.message
|
|
209
|
+
] }) }),
|
|
210
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-2 border-t border-border px-5 py-3", children: [
|
|
211
|
+
/* @__PURE__ */ jsx("div", { children: extras }),
|
|
212
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
213
|
+
/* @__PURE__ */ jsx(Button, { variant: "ghost", size: "sm", onClick: close, children: "Close" }),
|
|
214
|
+
/* @__PURE__ */ jsx(Button, { variant: "primary", size: "sm", onClick: retry, children: "Try again" }),
|
|
215
|
+
/* @__PURE__ */ jsx(
|
|
216
|
+
Button,
|
|
217
|
+
{
|
|
218
|
+
variant: "outline",
|
|
219
|
+
size: "sm",
|
|
220
|
+
onClick: () => {
|
|
221
|
+
if (typeof window !== "undefined") window.location.reload();
|
|
222
|
+
},
|
|
223
|
+
children: "Reload page"
|
|
224
|
+
}
|
|
225
|
+
)
|
|
226
|
+
] })
|
|
227
|
+
] })
|
|
228
|
+
]
|
|
229
|
+
}
|
|
230
|
+
) });
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
// src/react/SummonProvider.tsx
|
|
234
|
+
import { jsx as jsx2 } from "react/jsx-runtime";
|
|
229
235
|
function SummonProvider({
|
|
230
236
|
store,
|
|
231
237
|
ports,
|
|
@@ -263,49 +269,52 @@ function SummonProvider({
|
|
|
263
269
|
return /* @__PURE__ */ jsx2(Provider, { store: activeStore, context: SummonStoreContext, children: /* @__PURE__ */ jsx2(SummonPortsContext.Provider, { value: resolvedPorts, children: /* @__PURE__ */ jsx2(SummonConfigContext.Provider, { value: config, children }) }) });
|
|
264
270
|
}
|
|
265
271
|
|
|
266
|
-
// src/react
|
|
267
|
-
import { useCallback as useCallback2, useEffect as useEffect4, useMemo as useMemo3, useRef as useRef3, useState as useState2 } from "react";
|
|
272
|
+
// src/react.ts
|
|
268
273
|
import {
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
} from "@ai-matrx/summon";
|
|
272
|
-
import { selectIsOverlayOpen } from "@ai-matrx/summon";
|
|
273
|
-
|
|
274
|
-
// src/react/dispatchers.ts
|
|
275
|
-
import { closeOverlay, openOverlay } from "@ai-matrx/summon";
|
|
276
|
-
import { DEFAULT_INSTANCE_ID } from "@ai-matrx/summon";
|
|
277
|
-
function newInstanceId(overlayId) {
|
|
278
|
-
return `${overlayId}-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
|
|
279
|
-
}
|
|
280
|
-
function dispatchOpen(dispatch, overlayId, instanceId, data) {
|
|
281
|
-
dispatch(
|
|
282
|
-
openOverlay({
|
|
283
|
-
overlayId,
|
|
284
|
-
instanceId,
|
|
285
|
-
data: data ?? null
|
|
286
|
-
})
|
|
287
|
-
);
|
|
288
|
-
}
|
|
289
|
-
function dispatchClose(dispatch, overlayId, instanceId = DEFAULT_INSTANCE_ID) {
|
|
290
|
-
dispatch(closeOverlay({ overlayId, instanceId }));
|
|
291
|
-
}
|
|
274
|
+
defineOverlay,
|
|
275
|
+
CALLBACK_GROUP_KEY
|
|
276
|
+
} from "@ai-matrx/summon/root";
|
|
292
277
|
|
|
293
278
|
// src/react/events.ts
|
|
294
279
|
import { createEventChannel, getEventChannel } from "@ai-matrx/summon/handles";
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
channel.subscribe((message) => {
|
|
298
|
-
const handlers = getHandlers();
|
|
299
|
-
handlers?.[message.type]?.(message.payload);
|
|
300
|
-
});
|
|
301
|
-
return channel.id;
|
|
302
|
-
}
|
|
280
|
+
import { materializePendingChannels } from "@ai-matrx/summon/open";
|
|
281
|
+
import { registerOverlayEmitter } from "@ai-matrx/summon/root";
|
|
303
282
|
function emitOverlayEvent(channelId, type, payload) {
|
|
283
|
+
materializePendingChannels(createEventChannel);
|
|
304
284
|
getEventChannel(channelId)?.emit({ type, payload });
|
|
305
285
|
}
|
|
286
|
+
registerOverlayEmitter(emitOverlayEvent);
|
|
287
|
+
|
|
288
|
+
// src/react/SummonHost.tsx
|
|
289
|
+
import { Activity, memo as memo2, useCallback as useCallback2, useEffect as useEffect4, useRef as useRef3, useState as useState2 } from "react";
|
|
290
|
+
import { releaseOverlayInstance } from "@ai-matrx/summon";
|
|
291
|
+
import { registerOverlayMeta } from "@ai-matrx/summon";
|
|
292
|
+
import { closeOverlaysBoundToPage, overlayIdsBoundToPage, selectOpenInstances } from "@ai-matrx/summon";
|
|
293
|
+
import { instanceKey as toInstanceKey } from "@ai-matrx/summon";
|
|
294
|
+
import { dispatchClose } from "@ai-matrx/summon/root";
|
|
295
|
+
|
|
296
|
+
// src/react/hostRenders.ts
|
|
297
|
+
import { createContext as createContext2 } from "react";
|
|
298
|
+
var HostRendersContext = createContext2(null);
|
|
299
|
+
var MISSING_RENDER_ERROR = "OverlayRenderMissingError";
|
|
300
|
+
var missing = /* @__PURE__ */ new Map();
|
|
301
|
+
function missingRenderLoader(overlayId) {
|
|
302
|
+
let loader = missing.get(overlayId);
|
|
303
|
+
if (!loader) {
|
|
304
|
+
const message = `Overlay "${overlayId}" is open but has no render module: its definition has no \`render\` and <SummonHost renders> has no "${overlayId}" entry.`;
|
|
305
|
+
loader = () => {
|
|
306
|
+
if (process.env.NODE_ENV !== "production") console.error(`[summon] ${message}`);
|
|
307
|
+
const error = new Error(message);
|
|
308
|
+
error.name = MISSING_RENDER_ERROR;
|
|
309
|
+
return Promise.reject(error);
|
|
310
|
+
};
|
|
311
|
+
missing.set(overlayId, loader);
|
|
312
|
+
}
|
|
313
|
+
return loader;
|
|
314
|
+
}
|
|
306
315
|
|
|
307
316
|
// src/react/instanceBody.tsx
|
|
308
|
-
import { Suspense, memo, useContext as
|
|
317
|
+
import { Suspense, memo, useContext as useContext2, useEffect as useEffect3, useMemo as useMemo2, useRef as useRef2 } from "react";
|
|
309
318
|
|
|
310
319
|
// src/react/OverlayErrorBoundary.tsx
|
|
311
320
|
import { Component } from "react";
|
|
@@ -356,20 +365,14 @@ var OverlayErrorBoundary = class extends Component {
|
|
|
356
365
|
};
|
|
357
366
|
|
|
358
367
|
// src/react/instance.tsx
|
|
359
|
-
import {
|
|
368
|
+
import { useCallback } from "react";
|
|
360
369
|
import { selectOverlayStateValue, setOverlayStateValue } from "@ai-matrx/summon";
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
}
|
|
368
|
-
return value;
|
|
369
|
-
}
|
|
370
|
-
function useOptionalOverlayInstance() {
|
|
371
|
-
return useContext2(OverlayInstanceContext);
|
|
372
|
-
}
|
|
370
|
+
import { useOverlayInstance } from "@ai-matrx/summon/root";
|
|
371
|
+
import {
|
|
372
|
+
OverlayInstanceContext,
|
|
373
|
+
useOverlayInstance as useOverlayInstance2,
|
|
374
|
+
useOptionalOverlayInstance
|
|
375
|
+
} from "@ai-matrx/summon/root";
|
|
373
376
|
function useOverlayState(name, initial) {
|
|
374
377
|
const { instanceKey } = useOverlayInstance();
|
|
375
378
|
const dispatch = useSummonDispatch();
|
|
@@ -390,26 +393,6 @@ function useOverlayState(name, initial) {
|
|
|
390
393
|
return [value, setValue];
|
|
391
394
|
}
|
|
392
395
|
|
|
393
|
-
// src/react/hostRenders.ts
|
|
394
|
-
import { createContext as createContext3 } from "react";
|
|
395
|
-
var HostRendersContext = createContext3(null);
|
|
396
|
-
var MISSING_RENDER_ERROR = "OverlayRenderMissingError";
|
|
397
|
-
var missing = /* @__PURE__ */ new Map();
|
|
398
|
-
function missingRenderLoader(overlayId) {
|
|
399
|
-
let loader = missing.get(overlayId);
|
|
400
|
-
if (!loader) {
|
|
401
|
-
const message = `Overlay "${overlayId}" is open but has no render module: its definition has no \`render\` and <SummonHost renders> has no "${overlayId}" entry.`;
|
|
402
|
-
loader = () => {
|
|
403
|
-
if (process.env.NODE_ENV !== "production") console.error(`[summon] ${message}`);
|
|
404
|
-
const error = new Error(message);
|
|
405
|
-
error.name = MISSING_RENDER_ERROR;
|
|
406
|
-
return Promise.reject(error);
|
|
407
|
-
};
|
|
408
|
-
missing.set(overlayId, loader);
|
|
409
|
-
}
|
|
410
|
-
return loader;
|
|
411
|
-
}
|
|
412
|
-
|
|
413
396
|
// src/react/instanceBody.tsx
|
|
414
397
|
import { jsx as jsx4 } from "react/jsx-runtime";
|
|
415
398
|
function LazyRender({ overlayId, instanceId, data, hidden, close, render, attemptRef }) {
|
|
@@ -423,7 +406,7 @@ function createInstanceBody(overlayId, label, ownRender, parse, refusable) {
|
|
|
423
406
|
function OverlayInstanceBody({ instanceId, instanceKey, data, hidden, close }) {
|
|
424
407
|
const config = useSummonConfig();
|
|
425
408
|
const ports = useSummonPorts();
|
|
426
|
-
const hostRenders =
|
|
409
|
+
const hostRenders = useContext2(HostRendersContext);
|
|
427
410
|
const hostRender = ownRender ? void 0 : hostRenders?.[overlayId];
|
|
428
411
|
const render = ownRender ?? hostRender ?? missingRenderLoader(overlayId);
|
|
429
412
|
const attemptRef = useRef2(0);
|
|
@@ -476,104 +459,7 @@ function createInstanceBody(overlayId, label, ownRender, parse, refusable) {
|
|
|
476
459
|
return memo(OverlayInstanceBody);
|
|
477
460
|
}
|
|
478
461
|
|
|
479
|
-
// src/react/defineOverlay.tsx
|
|
480
|
-
var CALLBACK_GROUP_KEY = "callbackGroupId";
|
|
481
|
-
function openWith(dispatch, id, multi, options) {
|
|
482
|
-
const instanceId = options?.instanceId ?? (multi ? newInstanceId(id) : DEFAULT_INSTANCE_ID2);
|
|
483
|
-
const key = toInstanceKey(id, instanceId);
|
|
484
|
-
const data = {};
|
|
485
|
-
const given = options?.data;
|
|
486
|
-
if (typeof given === "object" && given !== null) Object.assign(data, given);
|
|
487
|
-
const handlers = options?.handlers;
|
|
488
|
-
if (handlers) data[CALLBACK_GROUP_KEY] = openOverlayEventChannel(key, () => handlers);
|
|
489
|
-
dispatchOpen(dispatch, id, instanceId, data);
|
|
490
|
-
return { overlayId: id, instanceId, close: () => dispatchClose(dispatch, id, instanceId) };
|
|
491
|
-
}
|
|
492
|
-
function dataSignature(data) {
|
|
493
|
-
try {
|
|
494
|
-
return JSON.stringify(data, (_key, value) => typeof value === "function" ? void 0 : value);
|
|
495
|
-
} catch {
|
|
496
|
-
return String(Date.now());
|
|
497
|
-
}
|
|
498
|
-
}
|
|
499
|
-
function defineOverlay() {
|
|
500
|
-
return function define(spec) {
|
|
501
|
-
const id = spec.id;
|
|
502
|
-
const multi = spec.instance === "multi";
|
|
503
|
-
const parse = spec.parse ?? ((raw) => raw);
|
|
504
|
-
const Body = createInstanceBody(id, spec.label, spec.render, parse, spec.parse !== void 0);
|
|
505
|
-
const meta = spec;
|
|
506
|
-
function useSummon() {
|
|
507
|
-
const dispatch = useSummonDispatch();
|
|
508
|
-
return useCallback2((options) => openWith(dispatch, id, multi, options), [dispatch]);
|
|
509
|
-
}
|
|
510
|
-
function useIsOpen(instanceId = DEFAULT_INSTANCE_ID2) {
|
|
511
|
-
return useSummonSelector((state) => selectIsOverlayOpen(state, id, instanceId));
|
|
512
|
-
}
|
|
513
|
-
function useClose() {
|
|
514
|
-
const dispatch = useSummonDispatch();
|
|
515
|
-
return useCallback2((instanceId) => dispatchClose(dispatch, id, instanceId ?? DEFAULT_INSTANCE_ID2), [dispatch]);
|
|
516
|
-
}
|
|
517
|
-
function useEmit() {
|
|
518
|
-
const instance = useOptionalOverlayInstance();
|
|
519
|
-
const channelId = instance?.overlayId === id ? instance.rawData?.[CALLBACK_GROUP_KEY] : void 0;
|
|
520
|
-
return useCallback2(
|
|
521
|
-
(event, payload) => {
|
|
522
|
-
if (typeof channelId === "string") emitOverlayEvent(channelId, event, payload);
|
|
523
|
-
},
|
|
524
|
-
[channelId]
|
|
525
|
-
);
|
|
526
|
-
}
|
|
527
|
-
function Controller(props) {
|
|
528
|
-
const dispatch = useSummonDispatch();
|
|
529
|
-
const [ownInstanceId] = useState2(() => multi ? newInstanceId(id) : DEFAULT_INSTANCE_ID2);
|
|
530
|
-
const instanceId = props.instanceId ?? ownInstanceId;
|
|
531
|
-
const handlersRef = useRef3(props.handlers);
|
|
532
|
-
handlersRef.current = props.handlers;
|
|
533
|
-
const hasHandlers = props.handlers !== void 0;
|
|
534
|
-
const data = useMemo3(() => {
|
|
535
|
-
const out = {};
|
|
536
|
-
for (const [key, value] of Object.entries(props)) {
|
|
537
|
-
if (key !== "instanceId" && key !== "handlers") out[key] = value;
|
|
538
|
-
}
|
|
539
|
-
return out;
|
|
540
|
-
}, [props]);
|
|
541
|
-
const signature = dataSignature(data);
|
|
542
|
-
const dataRef = useRef3(data);
|
|
543
|
-
dataRef.current = data;
|
|
544
|
-
useEffect4(() => {
|
|
545
|
-
const key = toInstanceKey(id, instanceId);
|
|
546
|
-
const open = { ...dataRef.current };
|
|
547
|
-
if (hasHandlers) open[CALLBACK_GROUP_KEY] = openOverlayEventChannel(key, () => handlersRef.current);
|
|
548
|
-
dispatchOpen(dispatch, id, instanceId, open);
|
|
549
|
-
return () => dispatchClose(dispatch, id, instanceId);
|
|
550
|
-
}, [dispatch, instanceId, signature, hasHandlers]);
|
|
551
|
-
return null;
|
|
552
|
-
}
|
|
553
|
-
Controller.displayName = `${id}Controller`;
|
|
554
|
-
return {
|
|
555
|
-
...spec,
|
|
556
|
-
id,
|
|
557
|
-
label: spec.label,
|
|
558
|
-
instance: multi ? "multi" : "single",
|
|
559
|
-
keepAlive: spec.keepAlive ?? "none",
|
|
560
|
-
meta,
|
|
561
|
-
Body,
|
|
562
|
-
useSummon,
|
|
563
|
-
Controller,
|
|
564
|
-
useIsOpen,
|
|
565
|
-
useClose,
|
|
566
|
-
useEmit
|
|
567
|
-
};
|
|
568
|
-
};
|
|
569
|
-
}
|
|
570
|
-
|
|
571
462
|
// src/react/SummonHost.tsx
|
|
572
|
-
import { Activity, memo as memo2, useCallback as useCallback3, useEffect as useEffect5, useRef as useRef4, useState as useState3 } from "react";
|
|
573
|
-
import { releaseOverlayInstance } from "@ai-matrx/summon";
|
|
574
|
-
import { registerOverlayMeta } from "@ai-matrx/summon";
|
|
575
|
-
import { closeOverlaysBoundToPage, overlayIdsBoundToPage, selectOpenInstances } from "@ai-matrx/summon";
|
|
576
|
-
import { instanceKey as toInstanceKey2 } from "@ai-matrx/summon";
|
|
577
463
|
import { Fragment, jsx as jsx5 } from "react/jsx-runtime";
|
|
578
464
|
function asRawData(data) {
|
|
579
465
|
return typeof data === "object" && data !== null && !Array.isArray(data) ? data : null;
|
|
@@ -588,11 +474,22 @@ function sameInstances(a, b) {
|
|
|
588
474
|
}
|
|
589
475
|
return true;
|
|
590
476
|
}
|
|
477
|
+
var bodies = /* @__PURE__ */ new WeakMap();
|
|
478
|
+
function bodyOf(definition) {
|
|
479
|
+
let body = bodies.get(definition);
|
|
480
|
+
if (!body) {
|
|
481
|
+
const parse = definition.parse ?? ((raw) => raw);
|
|
482
|
+
const render = definition.render;
|
|
483
|
+
body = createInstanceBody(definition.id, definition.label, render, parse, definition.parse !== void 0);
|
|
484
|
+
bodies.set(definition, body);
|
|
485
|
+
}
|
|
486
|
+
return body;
|
|
487
|
+
}
|
|
591
488
|
var NO_RETAINED = /* @__PURE__ */ new Map();
|
|
592
489
|
function useCloseOnNavigation() {
|
|
593
490
|
const ports = useSummonPorts();
|
|
594
491
|
const dispatch = useSummonDispatch();
|
|
595
|
-
|
|
492
|
+
useEffect4(() => {
|
|
596
493
|
const router = ports.router;
|
|
597
494
|
let previous = router.pathname();
|
|
598
495
|
return router.subscribe(() => {
|
|
@@ -606,17 +503,17 @@ function useCloseOnNavigation() {
|
|
|
606
503
|
}
|
|
607
504
|
var InstanceSlot = memo2(function InstanceSlot2({ definition, instanceId, data, hidden }) {
|
|
608
505
|
const dispatch = useSummonDispatch();
|
|
609
|
-
const close =
|
|
610
|
-
const Body = definition
|
|
611
|
-
return /* @__PURE__ */ jsx5(Body, { instanceId, instanceKey:
|
|
506
|
+
const close = useCallback2(() => dispatchClose(dispatch, definition.id, instanceId), [dispatch, definition.id, instanceId]);
|
|
507
|
+
const Body = bodyOf(definition);
|
|
508
|
+
return /* @__PURE__ */ jsx5(Body, { instanceId, instanceKey: toInstanceKey(definition.id, instanceId), data, hidden, close });
|
|
612
509
|
});
|
|
613
510
|
var DefinitionSlot = memo2(function DefinitionSlot2({ definition }) {
|
|
614
511
|
const { keepAlive } = useSummonConfig();
|
|
615
512
|
const dispatch = useSummonDispatch();
|
|
616
513
|
const open = useSummonSelector((state) => selectOpenInstances(state, definition.id), sameInstances);
|
|
617
514
|
const keepHidden = definition.keepAlive === "hidden";
|
|
618
|
-
const [retained, setRetained] =
|
|
619
|
-
const [previousOpen, setPreviousOpen] =
|
|
515
|
+
const [retained, setRetained] = useState2(NO_RETAINED);
|
|
516
|
+
const [previousOpen, setPreviousOpen] = useState2(open);
|
|
620
517
|
if (previousOpen !== open) {
|
|
621
518
|
setPreviousOpen(open);
|
|
622
519
|
if (keepHidden) {
|
|
@@ -629,13 +526,13 @@ var DefinitionSlot = memo2(function DefinitionSlot2({ definition }) {
|
|
|
629
526
|
setRetained(next);
|
|
630
527
|
}
|
|
631
528
|
}
|
|
632
|
-
const registered =
|
|
633
|
-
|
|
529
|
+
const registered = useRef3(/* @__PURE__ */ new Set());
|
|
530
|
+
useEffect4(() => {
|
|
634
531
|
const seen = registered.current;
|
|
635
532
|
for (const instanceId of retained.keys()) {
|
|
636
533
|
if (seen.has(instanceId)) continue;
|
|
637
534
|
seen.add(instanceId);
|
|
638
|
-
const key =
|
|
535
|
+
const key = toInstanceKey(definition.id, instanceId);
|
|
639
536
|
keepAlive.retain(key, () => {
|
|
640
537
|
seen.delete(instanceId);
|
|
641
538
|
releaseOverlayInstance(dispatch, key);
|
|
@@ -650,14 +547,14 @@ var DefinitionSlot = memo2(function DefinitionSlot2({ definition }) {
|
|
|
650
547
|
for (const instanceId of [...seen]) {
|
|
651
548
|
if (retained.has(instanceId)) continue;
|
|
652
549
|
seen.delete(instanceId);
|
|
653
|
-
keepAlive.release(
|
|
550
|
+
keepAlive.release(toInstanceKey(definition.id, instanceId));
|
|
654
551
|
}
|
|
655
552
|
}, [retained, keepAlive, definition.id, dispatch]);
|
|
656
|
-
|
|
553
|
+
useEffect4(() => {
|
|
657
554
|
const seen = registered.current;
|
|
658
555
|
return () => {
|
|
659
556
|
for (const instanceId of seen) {
|
|
660
|
-
const key =
|
|
557
|
+
const key = toInstanceKey(definition.id, instanceId);
|
|
661
558
|
keepAlive.release(key);
|
|
662
559
|
releaseOverlayInstance(dispatch, key);
|
|
663
560
|
}
|
|
@@ -682,7 +579,7 @@ var DefinitionSlot = memo2(function DefinitionSlot2({ definition }) {
|
|
|
682
579
|
return /* @__PURE__ */ jsx5(Fragment, { children: nodes });
|
|
683
580
|
});
|
|
684
581
|
function SummonHost({ definitions, renders }) {
|
|
685
|
-
const registeredFor =
|
|
582
|
+
const registeredFor = useRef3(null);
|
|
686
583
|
if (registeredFor.current !== definitions) {
|
|
687
584
|
registerOverlayMeta(definitions.map((definition) => definition.meta));
|
|
688
585
|
registeredFor.current = definitions;
|
|
@@ -691,41 +588,45 @@ function SummonHost({ definitions, renders }) {
|
|
|
691
588
|
return /* @__PURE__ */ jsx5(HostRendersContext.Provider, { value: renders ?? null, children: definitions.map((definition) => /* @__PURE__ */ jsx5(DefinitionSlot, { definition }, definition.id)) });
|
|
692
589
|
}
|
|
693
590
|
|
|
591
|
+
// src/react.ts
|
|
592
|
+
import { SummonRoot, configureSummonHost } from "@ai-matrx/summon/root";
|
|
593
|
+
|
|
694
594
|
// src/react/hooks.ts
|
|
695
|
-
import { useCallback as
|
|
595
|
+
import { useCallback as useCallback3 } from "react";
|
|
696
596
|
import { getOverlayMeta } from "@ai-matrx/summon";
|
|
697
|
-
import { selectIsOverlayOpen
|
|
698
|
-
import { DEFAULT_INSTANCE_ID
|
|
699
|
-
|
|
700
|
-
|
|
597
|
+
import { selectIsOverlayOpen } from "@ai-matrx/summon";
|
|
598
|
+
import { DEFAULT_INSTANCE_ID } from "@ai-matrx/summon";
|
|
599
|
+
import { dispatchClose as dispatchClose2, dispatchOpen, newInstanceId } from "@ai-matrx/summon/root";
|
|
600
|
+
function useIsOverlayOpen(overlayId, instanceId = DEFAULT_INSTANCE_ID) {
|
|
601
|
+
return useSummonSelector((state) => selectIsOverlayOpen(state, overlayId, instanceId));
|
|
701
602
|
}
|
|
702
603
|
function useOpenOverlay(overlayId) {
|
|
703
604
|
const dispatch = useSummonDispatch();
|
|
704
|
-
return
|
|
605
|
+
return useCallback3(
|
|
705
606
|
(options) => {
|
|
706
607
|
const multi = getOverlayMeta(overlayId)?.instance === "multi";
|
|
707
|
-
const instanceId = options?.instanceId ?? (multi ? newInstanceId(overlayId) :
|
|
608
|
+
const instanceId = options?.instanceId ?? (multi ? newInstanceId(overlayId) : DEFAULT_INSTANCE_ID);
|
|
708
609
|
dispatchOpen(dispatch, overlayId, instanceId, options?.data ?? null);
|
|
709
|
-
return { overlayId, instanceId, close: () =>
|
|
610
|
+
return { overlayId, instanceId, close: () => dispatchClose2(dispatch, overlayId, instanceId) };
|
|
710
611
|
},
|
|
711
612
|
[dispatch, overlayId]
|
|
712
613
|
);
|
|
713
614
|
}
|
|
714
|
-
function useCloseOverlay(overlayId, instanceId =
|
|
615
|
+
function useCloseOverlay(overlayId, instanceId = DEFAULT_INSTANCE_ID) {
|
|
715
616
|
const dispatch = useSummonDispatch();
|
|
716
|
-
return
|
|
617
|
+
return useCallback3(() => dispatchClose2(dispatch, overlayId, instanceId), [dispatch, overlayId, instanceId]);
|
|
717
618
|
}
|
|
718
619
|
|
|
719
620
|
// src/react/useOverlayLink.ts
|
|
720
|
-
import { useEffect as
|
|
621
|
+
import { useEffect as useEffect5, useMemo as useMemo3 } from "react";
|
|
721
622
|
import { registerSyncEntry, unregisterSyncEntry } from "@ai-matrx/summon";
|
|
722
623
|
function useOverlayLink(linkKey, id, args) {
|
|
723
624
|
const dispatch = useSummonDispatch();
|
|
724
625
|
const argsKey = args ? JSON.stringify(
|
|
725
626
|
Object.keys(args).sort().map((k) => [k, args[k]])
|
|
726
627
|
) : "";
|
|
727
|
-
const stableArgs =
|
|
728
|
-
|
|
628
|
+
const stableArgs = useMemo3(() => args ? { ...args } : void 0, [argsKey]);
|
|
629
|
+
useEffect5(() => {
|
|
729
630
|
if (!linkKey || !id) return void 0;
|
|
730
631
|
dispatch(registerSyncEntry(stableArgs ? { typeKey: linkKey, instanceId: id, args: stableArgs } : { typeKey: linkKey, instanceId: id }));
|
|
731
632
|
return () => {
|
|
@@ -744,9 +645,12 @@ export {
|
|
|
744
645
|
OverlayLoadingFallback,
|
|
745
646
|
SummonHost,
|
|
746
647
|
SummonProvider,
|
|
648
|
+
SummonRoot,
|
|
747
649
|
SummonStoreContext,
|
|
748
650
|
chunkTimeoutError,
|
|
651
|
+
configureSummonHost,
|
|
749
652
|
defineOverlay,
|
|
653
|
+
emitOverlayEvent,
|
|
750
654
|
normalizeOverlayError,
|
|
751
655
|
useCloseOnNavigation,
|
|
752
656
|
useCloseOverlay,
|
|
@@ -755,7 +659,7 @@ export {
|
|
|
755
659
|
useOptionalOverlayInstance,
|
|
756
660
|
useOptionalSummonPorts,
|
|
757
661
|
useOptionalSummonStore,
|
|
758
|
-
useOverlayInstance,
|
|
662
|
+
useOverlayInstance2 as useOverlayInstance,
|
|
759
663
|
useOverlayLink,
|
|
760
664
|
useOverlayState,
|
|
761
665
|
useSummonDispatch,
|