samandesk 2.0.0-beta1.0 → 2.0.0-beta2.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.
- package/dist/saman-desk.js +256 -960
- package/dist/saman-desk.umd.cjs +1 -1
- package/dist/src/adapters/react-native/index.d.ts +30 -0
- package/dist/src/adapters/web/index.d.ts +16 -0
- package/dist/src/core/index.d.ts +29 -0
- package/dist/src/core/types.d.ts +50 -0
- package/dist/src/index.d.ts +3 -53
- package/package.json +1 -1
- package/dist/src/data.d.ts +0 -47
- package/dist/src/events.d.ts +0 -16
- package/dist/src/interoperation.d.ts +0 -22
package/dist/saman-desk.js
CHANGED
|
@@ -1,1016 +1,312 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
};
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
const frame = document.createElement("iframe");
|
|
14
|
-
let theme;
|
|
15
|
-
let color;
|
|
16
|
-
let language;
|
|
17
|
-
let linkHandler = (link) => window.open(link, "_blank", "noopener");
|
|
18
|
-
const backdrop = document.createElement("div");
|
|
19
|
-
function setToken(newToken) {
|
|
20
|
-
token = newToken;
|
|
21
|
-
}
|
|
22
|
-
function getToken() {
|
|
23
|
-
return token;
|
|
24
|
-
}
|
|
25
|
-
function clearFrame() {
|
|
26
|
-
frame.src = "";
|
|
27
|
-
}
|
|
28
|
-
function setFrameSrc(src) {
|
|
29
|
-
frame.src = src;
|
|
30
|
-
}
|
|
31
|
-
function getFrame() {
|
|
32
|
-
return frame;
|
|
33
|
-
}
|
|
34
|
-
function getTheme() {
|
|
35
|
-
return { theme, color };
|
|
36
|
-
}
|
|
37
|
-
function getLanguage() {
|
|
38
|
-
return { language };
|
|
39
|
-
}
|
|
40
|
-
function setTheme(newTheme) {
|
|
41
|
-
theme = newTheme.darkMode;
|
|
42
|
-
color = newTheme.color;
|
|
43
|
-
}
|
|
44
|
-
function setLanguage(newLanguage) {
|
|
45
|
-
language = newLanguage;
|
|
46
|
-
}
|
|
47
|
-
function getBackdrop() {
|
|
48
|
-
return backdrop;
|
|
49
|
-
}
|
|
50
|
-
function setOpenLinkFn(fn) {
|
|
51
|
-
if (fn) linkHandler = fn;
|
|
52
|
-
}
|
|
53
|
-
function getOpenLinkFn() {
|
|
54
|
-
return linkHandler;
|
|
55
|
-
}
|
|
56
|
-
const readyEvent = new Event("ready");
|
|
57
|
-
const openEvent = new Event("open");
|
|
58
|
-
const closeEvent = new Event("close");
|
|
59
|
-
const guestReadyEvent = new Event("guest-ready");
|
|
60
|
-
function getReadyEvent() {
|
|
61
|
-
return readyEvent;
|
|
62
|
-
}
|
|
63
|
-
function getOpenEvent() {
|
|
64
|
-
return openEvent;
|
|
65
|
-
}
|
|
66
|
-
function getCloseEvent() {
|
|
67
|
-
return closeEvent;
|
|
68
|
-
}
|
|
69
|
-
function setGuestReadyEvent() {
|
|
70
|
-
return guestReadyEvent;
|
|
71
|
-
}
|
|
72
|
-
var PenpalError = class extends Error {
|
|
73
|
-
constructor(code, message) {
|
|
74
|
-
super(message);
|
|
75
|
-
__publicField(this, "code");
|
|
76
|
-
this.name = "PenpalError";
|
|
77
|
-
this.code = code;
|
|
1
|
+
const __vite_import_meta_env__ = {};
|
|
2
|
+
class SamanDeskCore {
|
|
3
|
+
constructor(config) {
|
|
4
|
+
this.runPromises = {};
|
|
5
|
+
this.promiseCount = 0;
|
|
6
|
+
this.isReady = false;
|
|
7
|
+
this.config = {
|
|
8
|
+
siteUrl: this.defaultSiteUrl,
|
|
9
|
+
language: "fa",
|
|
10
|
+
theme: { darkMode: "light", color: "default" },
|
|
11
|
+
...config
|
|
12
|
+
};
|
|
78
13
|
}
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
var serializeError = (error) => ({
|
|
82
|
-
name: error.name,
|
|
83
|
-
message: error.message,
|
|
84
|
-
stack: error.stack,
|
|
85
|
-
penpalCode: error instanceof PenpalError_default ? error.code : void 0
|
|
86
|
-
});
|
|
87
|
-
var deserializeError = ({
|
|
88
|
-
name,
|
|
89
|
-
message,
|
|
90
|
-
stack,
|
|
91
|
-
penpalCode
|
|
92
|
-
}) => {
|
|
93
|
-
const deserializedError = penpalCode ? new PenpalError_default(penpalCode, message) : new Error(message);
|
|
94
|
-
deserializedError.name = name;
|
|
95
|
-
deserializedError.stack = stack;
|
|
96
|
-
return deserializedError;
|
|
97
|
-
};
|
|
98
|
-
var brand = Symbol("Reply");
|
|
99
|
-
var Reply = (_a = class {
|
|
100
|
-
constructor(value, options) {
|
|
101
|
-
__publicField(this, "value");
|
|
102
|
-
__publicField(this, "transferables");
|
|
103
|
-
// Allows TypeScript to distinguish between an actual instance of this
|
|
104
|
-
// class versus an object that looks structurally similar.
|
|
105
|
-
// eslint-disable-next-line no-unused-private-class-members
|
|
106
|
-
__privateAdd(this, _brand, brand);
|
|
107
|
-
this.value = value;
|
|
108
|
-
this.transferables = options == null ? void 0 : options.transferables;
|
|
14
|
+
get defaultSiteUrl() {
|
|
15
|
+
return (__vite_import_meta_env__ == null ? void 0 : __vite_import_meta_env__.VITE_DEV_MODE) === "1" ? "http://localhost:2525" : "https://samandesk.com";
|
|
109
16
|
}
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
var isObject = (value) => {
|
|
114
|
-
return typeof value === "object" && value !== null;
|
|
115
|
-
};
|
|
116
|
-
var isFunction = (value) => {
|
|
117
|
-
return typeof value === "function";
|
|
118
|
-
};
|
|
119
|
-
var isMessage = (data) => {
|
|
120
|
-
return isObject(data) && data.namespace === namespace_default;
|
|
121
|
-
};
|
|
122
|
-
var isSynMessage = (message) => {
|
|
123
|
-
return message.type === "SYN";
|
|
124
|
-
};
|
|
125
|
-
var isAck1Message = (message) => {
|
|
126
|
-
return message.type === "ACK1";
|
|
127
|
-
};
|
|
128
|
-
var isAck2Message = (message) => {
|
|
129
|
-
return message.type === "ACK2";
|
|
130
|
-
};
|
|
131
|
-
var isCallMessage = (message) => {
|
|
132
|
-
return message.type === "CALL";
|
|
133
|
-
};
|
|
134
|
-
var isReplyMessage = (message) => {
|
|
135
|
-
return message.type === "REPLY";
|
|
136
|
-
};
|
|
137
|
-
var isDestroyMessage = (message) => {
|
|
138
|
-
return message.type === "DESTROY";
|
|
139
|
-
};
|
|
140
|
-
var extractMethodPathsFromMethods = (methods, currentPath = []) => {
|
|
141
|
-
const methodPaths = [];
|
|
142
|
-
for (const key of Object.keys(methods)) {
|
|
143
|
-
const value = methods[key];
|
|
144
|
-
if (isFunction(value)) {
|
|
145
|
-
methodPaths.push([...currentPath, key]);
|
|
146
|
-
} else if (isObject(value)) {
|
|
147
|
-
methodPaths.push(
|
|
148
|
-
...extractMethodPathsFromMethods(value, [...currentPath, key])
|
|
149
|
-
);
|
|
17
|
+
getInitialUrl() {
|
|
18
|
+
if (this.config.verifiedToken) {
|
|
19
|
+
return `${this.config.siteUrl}/setup-interoperation/${this.config.verifiedToken}`;
|
|
150
20
|
}
|
|
21
|
+
return `${this.config.siteUrl}/guest-login/${this.config.workspaceID}`;
|
|
151
22
|
}
|
|
152
|
-
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
(
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
return isFunction(result) ? result : void 0;
|
|
162
|
-
};
|
|
163
|
-
var formatMethodPath = (methodPath) => {
|
|
164
|
-
return methodPath.join(".");
|
|
165
|
-
};
|
|
166
|
-
var createErrorReplyMessage = (channel, callId, error) => ({
|
|
167
|
-
namespace: namespace_default,
|
|
168
|
-
channel,
|
|
169
|
-
type: "REPLY",
|
|
170
|
-
callId,
|
|
171
|
-
isError: true,
|
|
172
|
-
...error instanceof Error ? { value: serializeError(error), isSerializedErrorInstance: true } : { value: error }
|
|
173
|
-
});
|
|
174
|
-
var connectCallHandler = (messenger, methods, channel, log) => {
|
|
175
|
-
let isDestroyed = false;
|
|
176
|
-
const handleMessage = async (message) => {
|
|
177
|
-
if (isDestroyed) {
|
|
23
|
+
getOpenUrl(link) {
|
|
24
|
+
return link || `${this.config.siteUrl}/department-selection?token=${this.token}`;
|
|
25
|
+
}
|
|
26
|
+
handleIncomingMessage(message) {
|
|
27
|
+
if (!message || message.from !== "SamanDesk") return;
|
|
28
|
+
const { action, id, data } = message;
|
|
29
|
+
if (id !== void 0 && this.runPromises[id]) {
|
|
30
|
+
this.runPromises[id](data);
|
|
31
|
+
delete this.runPromises[id];
|
|
178
32
|
return;
|
|
179
33
|
}
|
|
180
|
-
|
|
181
|
-
|
|
34
|
+
switch (action) {
|
|
35
|
+
case "setToken":
|
|
36
|
+
this.handleSetToken(data);
|
|
37
|
+
break;
|
|
38
|
+
case "getConfig":
|
|
39
|
+
this.handleGetConfig(id);
|
|
40
|
+
break;
|
|
41
|
+
case "openLink":
|
|
42
|
+
this.handleOpenLink(data);
|
|
43
|
+
break;
|
|
44
|
+
case "setGuestReadyEvent":
|
|
45
|
+
this.handleSetGuestReadyEvent();
|
|
46
|
+
break;
|
|
47
|
+
case "close":
|
|
48
|
+
this.handleCloseFromInside();
|
|
49
|
+
break;
|
|
50
|
+
default:
|
|
51
|
+
console.warn(`[SamanDesk] Unhandled action: ${action}`);
|
|
182
52
|
}
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
throw new PenpalError_default(
|
|
191
|
-
"METHOD_NOT_FOUND",
|
|
192
|
-
`Method \`${formatMethodPath(methodPath)}\` is not found.`
|
|
193
|
-
);
|
|
194
|
-
}
|
|
195
|
-
let value = await method(...args);
|
|
196
|
-
if (value instanceof Reply_default) {
|
|
197
|
-
transferables = value.transferables;
|
|
198
|
-
value = await value.value;
|
|
53
|
+
}
|
|
54
|
+
handleSetToken(data) {
|
|
55
|
+
if (data && data.token) {
|
|
56
|
+
this.token = data.token;
|
|
57
|
+
this.isReady = true;
|
|
58
|
+
if (this.config.onReady) {
|
|
59
|
+
this.config.onReady(this.token);
|
|
199
60
|
}
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
channel,
|
|
203
|
-
type: "REPLY",
|
|
204
|
-
callId,
|
|
205
|
-
value
|
|
206
|
-
};
|
|
207
|
-
} catch (error) {
|
|
208
|
-
replyMessage = createErrorReplyMessage(channel, callId, error);
|
|
209
|
-
}
|
|
210
|
-
if (isDestroyed) {
|
|
211
|
-
return;
|
|
212
|
-
}
|
|
213
|
-
try {
|
|
214
|
-
log == null ? void 0 : log(`Sending ${formatMethodPath(methodPath)}() reply`, replyMessage);
|
|
215
|
-
messenger.sendMessage(replyMessage, transferables);
|
|
216
|
-
} catch (error) {
|
|
217
|
-
if (error.name === "DataCloneError") {
|
|
218
|
-
replyMessage = createErrorReplyMessage(channel, callId, error);
|
|
219
|
-
log == null ? void 0 : log(`Sending ${formatMethodPath(methodPath)}() reply`, replyMessage);
|
|
220
|
-
messenger.sendMessage(replyMessage);
|
|
61
|
+
if (this.config.onTokenChange) {
|
|
62
|
+
this.config.onTokenChange(this.token);
|
|
221
63
|
}
|
|
222
|
-
throw error;
|
|
223
64
|
}
|
|
224
|
-
};
|
|
225
|
-
messenger.addMessageHandler(handleMessage);
|
|
226
|
-
return () => {
|
|
227
|
-
isDestroyed = true;
|
|
228
|
-
messenger.removeMessageHandler(handleMessage);
|
|
229
|
-
};
|
|
230
|
-
};
|
|
231
|
-
var connectCallHandler_default = connectCallHandler;
|
|
232
|
-
var generateId_default = ((_b = crypto.randomUUID) == null ? void 0 : _b.bind(crypto)) ?? (() => new Array(4).fill(0).map(
|
|
233
|
-
() => Math.floor(Math.random() * Number.MAX_SAFE_INTEGER).toString(16)
|
|
234
|
-
).join("-"));
|
|
235
|
-
var brand2 = Symbol("CallOptions");
|
|
236
|
-
var CallOptions = (_c = class {
|
|
237
|
-
constructor(options) {
|
|
238
|
-
__publicField(this, "transferables");
|
|
239
|
-
__publicField(this, "timeout");
|
|
240
|
-
// Allows TypeScript to distinguish between an actual instance of this
|
|
241
|
-
// class versus an object that looks structurally similar.
|
|
242
|
-
// eslint-disable-next-line no-unused-private-class-members
|
|
243
|
-
__privateAdd(this, _brand2, brand2);
|
|
244
|
-
this.transferables = options == null ? void 0 : options.transferables;
|
|
245
|
-
this.timeout = options == null ? void 0 : options.timeout;
|
|
246
65
|
}
|
|
247
|
-
|
|
248
|
-
var
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
get(target, prop) {
|
|
256
|
-
if (prop === "then") {
|
|
257
|
-
return;
|
|
258
|
-
}
|
|
259
|
-
if (path.length && methodsToTreatAsNative.has(prop)) {
|
|
260
|
-
return Reflect.get(target, prop);
|
|
261
|
-
}
|
|
262
|
-
return createRemoteProxy(callback, log, [...path, prop]);
|
|
263
|
-
},
|
|
264
|
-
apply(target, _thisArg, args) {
|
|
265
|
-
return callback(path, args);
|
|
266
|
-
}
|
|
267
|
-
}
|
|
268
|
-
);
|
|
269
|
-
};
|
|
270
|
-
var getDestroyedConnectionMethodCallError = (methodPath) => {
|
|
271
|
-
return new PenpalError_default(
|
|
272
|
-
"CONNECTION_DESTROYED",
|
|
273
|
-
`Method call ${formatMethodPath(
|
|
274
|
-
methodPath
|
|
275
|
-
)}() failed due to destroyed connection`
|
|
276
|
-
);
|
|
277
|
-
};
|
|
278
|
-
var connectRemoteProxy = (messenger, channel, log) => {
|
|
279
|
-
let isDestroyed = false;
|
|
280
|
-
const replyHandlers = /* @__PURE__ */ new Map();
|
|
281
|
-
const handleMessage = (message) => {
|
|
282
|
-
if (!isReplyMessage(message)) {
|
|
283
|
-
return;
|
|
284
|
-
}
|
|
285
|
-
const { callId, value, isError, isSerializedErrorInstance } = message;
|
|
286
|
-
const replyHandler = replyHandlers.get(callId);
|
|
287
|
-
if (!replyHandler) {
|
|
288
|
-
return;
|
|
66
|
+
handleGetConfig(id) {
|
|
67
|
+
var _a, _b;
|
|
68
|
+
if (id !== void 0) {
|
|
69
|
+
this.sendResponse(id, "getConfig", {
|
|
70
|
+
color: ((_a = this.config.theme) == null ? void 0 : _a.color) || "default",
|
|
71
|
+
theme: ((_b = this.config.theme) == null ? void 0 : _b.darkMode) || "light",
|
|
72
|
+
language: this.config.language || "fa"
|
|
73
|
+
});
|
|
289
74
|
}
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
);
|
|
295
|
-
if (isError) {
|
|
296
|
-
replyHandler.reject(
|
|
297
|
-
isSerializedErrorInstance ? deserializeError(value) : value
|
|
298
|
-
);
|
|
75
|
+
}
|
|
76
|
+
handleOpenLink(data) {
|
|
77
|
+
if (this.config.linkHandler) {
|
|
78
|
+
this.config.linkHandler(data.link);
|
|
299
79
|
} else {
|
|
300
|
-
|
|
301
|
-
}
|
|
302
|
-
};
|
|
303
|
-
messenger.addMessageHandler(handleMessage);
|
|
304
|
-
const remoteProxy = createRemoteProxy((methodPath, args) => {
|
|
305
|
-
if (isDestroyed) {
|
|
306
|
-
throw getDestroyedConnectionMethodCallError(methodPath);
|
|
307
|
-
}
|
|
308
|
-
const callId = generateId_default();
|
|
309
|
-
const lastArg = args[args.length - 1];
|
|
310
|
-
const lastArgIsOptions = lastArg instanceof CallOptions_default;
|
|
311
|
-
const { timeout, transferables } = lastArgIsOptions ? lastArg : {};
|
|
312
|
-
const argsWithoutOptions = lastArgIsOptions ? args.slice(0, -1) : args;
|
|
313
|
-
return new Promise((resolve, reject) => {
|
|
314
|
-
const timeoutId = timeout !== void 0 ? window.setTimeout(() => {
|
|
315
|
-
replyHandlers.delete(callId);
|
|
316
|
-
reject(
|
|
317
|
-
new PenpalError_default(
|
|
318
|
-
"METHOD_CALL_TIMEOUT",
|
|
319
|
-
`Method call ${formatMethodPath(
|
|
320
|
-
methodPath
|
|
321
|
-
)}() timed out after ${timeout}ms`
|
|
322
|
-
)
|
|
323
|
-
);
|
|
324
|
-
}, timeout) : void 0;
|
|
325
|
-
replyHandlers.set(callId, { methodPath, resolve, reject, timeoutId });
|
|
326
|
-
try {
|
|
327
|
-
const callMessage = {
|
|
328
|
-
namespace: namespace_default,
|
|
329
|
-
channel,
|
|
330
|
-
type: "CALL",
|
|
331
|
-
id: callId,
|
|
332
|
-
methodPath,
|
|
333
|
-
args: argsWithoutOptions
|
|
334
|
-
};
|
|
335
|
-
log == null ? void 0 : log(`Sending ${formatMethodPath(methodPath)}() call`, callMessage);
|
|
336
|
-
messenger.sendMessage(callMessage, transferables);
|
|
337
|
-
} catch (error) {
|
|
338
|
-
reject(
|
|
339
|
-
new PenpalError_default("TRANSMISSION_FAILED", error.message)
|
|
340
|
-
);
|
|
341
|
-
}
|
|
342
|
-
});
|
|
343
|
-
}, log);
|
|
344
|
-
const destroy = () => {
|
|
345
|
-
isDestroyed = true;
|
|
346
|
-
messenger.removeMessageHandler(handleMessage);
|
|
347
|
-
for (const { methodPath, reject, timeoutId } of replyHandlers.values()) {
|
|
348
|
-
clearTimeout(timeoutId);
|
|
349
|
-
reject(getDestroyedConnectionMethodCallError(methodPath));
|
|
80
|
+
console.warn("[SamanDesk] openLink requested but no linkHandler configured.");
|
|
350
81
|
}
|
|
351
|
-
replyHandlers.clear();
|
|
352
|
-
};
|
|
353
|
-
return {
|
|
354
|
-
remoteProxy,
|
|
355
|
-
destroy
|
|
356
|
-
};
|
|
357
|
-
};
|
|
358
|
-
var connectRemoteProxy_default = connectRemoteProxy;
|
|
359
|
-
var getPromiseWithResolvers = () => {
|
|
360
|
-
let resolve;
|
|
361
|
-
let reject;
|
|
362
|
-
const promise = new Promise((res, rej) => {
|
|
363
|
-
resolve = res;
|
|
364
|
-
reject = rej;
|
|
365
|
-
});
|
|
366
|
-
return {
|
|
367
|
-
promise,
|
|
368
|
-
resolve,
|
|
369
|
-
reject
|
|
370
|
-
};
|
|
371
|
-
};
|
|
372
|
-
var getPromiseWithResolvers_default = getPromiseWithResolvers;
|
|
373
|
-
var DEPRECATED_PENPAL_PARTICIPANT_ID = "deprecated-penpal";
|
|
374
|
-
var isDeprecatedMessage = (data) => {
|
|
375
|
-
return isObject(data) && "penpal" in data;
|
|
376
|
-
};
|
|
377
|
-
var upgradeMethodPath = (methodPath) => methodPath.split(".");
|
|
378
|
-
var downgradeMethodPath = (methodPath) => methodPath.join(".");
|
|
379
|
-
var stringifyUnknownMessage = (message) => {
|
|
380
|
-
try {
|
|
381
|
-
return JSON.stringify(message);
|
|
382
|
-
} catch (_) {
|
|
383
|
-
return String(message);
|
|
384
82
|
}
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
`Unexpected message to translate: ${stringifyUnknownMessage(message)}`
|
|
390
|
-
);
|
|
391
|
-
};
|
|
392
|
-
var upgradeMessage = (message) => {
|
|
393
|
-
if (message.penpal === "syn") {
|
|
394
|
-
return {
|
|
395
|
-
namespace: namespace_default,
|
|
396
|
-
channel: void 0,
|
|
397
|
-
type: "SYN",
|
|
398
|
-
participantId: DEPRECATED_PENPAL_PARTICIPANT_ID
|
|
399
|
-
};
|
|
400
|
-
}
|
|
401
|
-
if (message.penpal === "ack") {
|
|
402
|
-
return {
|
|
403
|
-
namespace: namespace_default,
|
|
404
|
-
channel: void 0,
|
|
405
|
-
type: "ACK2"
|
|
406
|
-
};
|
|
407
|
-
}
|
|
408
|
-
if (message.penpal === "call") {
|
|
409
|
-
return {
|
|
410
|
-
namespace: namespace_default,
|
|
411
|
-
channel: void 0,
|
|
412
|
-
type: "CALL",
|
|
413
|
-
// Actually converting the ID to a string would break communication.
|
|
414
|
-
id: message.id,
|
|
415
|
-
methodPath: upgradeMethodPath(message.methodName),
|
|
416
|
-
args: message.args
|
|
417
|
-
};
|
|
418
|
-
}
|
|
419
|
-
if (message.penpal === "reply") {
|
|
420
|
-
if (message.resolution === "fulfilled") {
|
|
421
|
-
return {
|
|
422
|
-
namespace: namespace_default,
|
|
423
|
-
channel: void 0,
|
|
424
|
-
type: "REPLY",
|
|
425
|
-
// Actually converting the ID to a string would break communication.
|
|
426
|
-
callId: message.id,
|
|
427
|
-
value: message.returnValue
|
|
428
|
-
};
|
|
429
|
-
} else {
|
|
430
|
-
return {
|
|
431
|
-
namespace: namespace_default,
|
|
432
|
-
channel: void 0,
|
|
433
|
-
type: "REPLY",
|
|
434
|
-
// Actually converting the ID to a string would break communication.
|
|
435
|
-
callId: message.id,
|
|
436
|
-
isError: true,
|
|
437
|
-
...message.returnValueIsError ? {
|
|
438
|
-
value: message.returnValue,
|
|
439
|
-
isSerializedErrorInstance: true
|
|
440
|
-
} : {
|
|
441
|
-
value: message.returnValue
|
|
442
|
-
}
|
|
443
|
-
};
|
|
83
|
+
handleSetGuestReadyEvent() {
|
|
84
|
+
this.isReady = true;
|
|
85
|
+
if (this.config.onGuestReady) {
|
|
86
|
+
this.config.onGuestReady();
|
|
444
87
|
}
|
|
445
88
|
}
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
var downgradeMessage = (message) => {
|
|
449
|
-
if (isAck1Message(message)) {
|
|
450
|
-
return {
|
|
451
|
-
penpal: "synAck",
|
|
452
|
-
methodNames: message.methodPaths.map(downgradeMethodPath)
|
|
453
|
-
};
|
|
89
|
+
handleCloseFromInside() {
|
|
90
|
+
this.close();
|
|
454
91
|
}
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
// Actually converting the ID to a number would break communication.
|
|
459
|
-
id: message.id,
|
|
460
|
-
methodName: downgradeMethodPath(message.methodPath),
|
|
461
|
-
args: message.args
|
|
462
|
-
};
|
|
92
|
+
// To be implemented by adapters
|
|
93
|
+
sendMessage(message) {
|
|
94
|
+
throw new Error("sendMessage not implemented");
|
|
463
95
|
}
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
// Actually converting the ID to a number would break communication.
|
|
469
|
-
id: message.callId,
|
|
470
|
-
resolution: "rejected",
|
|
471
|
-
...message.isSerializedErrorInstance ? {
|
|
472
|
-
returnValue: message.value,
|
|
473
|
-
returnValueIsError: true
|
|
474
|
-
} : { returnValue: message.value }
|
|
475
|
-
};
|
|
476
|
-
} else {
|
|
477
|
-
return {
|
|
478
|
-
penpal: "reply",
|
|
479
|
-
// Actually converting the ID to a number would break communication.
|
|
480
|
-
id: message.callId,
|
|
481
|
-
resolution: "fulfilled",
|
|
482
|
-
returnValue: message.value
|
|
483
|
-
};
|
|
96
|
+
// To be implemented by adapters
|
|
97
|
+
close() {
|
|
98
|
+
if (this.config.onClose) {
|
|
99
|
+
this.config.onClose();
|
|
484
100
|
}
|
|
485
101
|
}
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
methods,
|
|
491
|
-
timeout,
|
|
492
|
-
channel,
|
|
493
|
-
log
|
|
494
|
-
}) => {
|
|
495
|
-
const participantId = generateId_default();
|
|
496
|
-
let remoteParticipantId;
|
|
497
|
-
const destroyHandlers = [];
|
|
498
|
-
let isComplete = false;
|
|
499
|
-
const methodPaths = extractMethodPathsFromMethods(methods);
|
|
500
|
-
const { promise, resolve, reject } = getPromiseWithResolvers_default();
|
|
501
|
-
const timeoutId = timeout !== void 0 ? setTimeout(() => {
|
|
502
|
-
reject(
|
|
503
|
-
new PenpalError_default(
|
|
504
|
-
"CONNECTION_TIMEOUT",
|
|
505
|
-
`Connection timed out after ${timeout}ms`
|
|
506
|
-
)
|
|
507
|
-
);
|
|
508
|
-
}, timeout) : void 0;
|
|
509
|
-
const destroy = () => {
|
|
510
|
-
for (const destroyHandler of destroyHandlers) {
|
|
511
|
-
destroyHandler();
|
|
512
|
-
}
|
|
513
|
-
};
|
|
514
|
-
const connectCallHandlerAndMethodProxies = () => {
|
|
515
|
-
if (isComplete) {
|
|
516
|
-
return;
|
|
517
|
-
}
|
|
518
|
-
destroyHandlers.push(connectCallHandler_default(messenger, methods, channel, log));
|
|
519
|
-
const { remoteProxy, destroy: destroyMethodProxies } = connectRemoteProxy_default(messenger, channel, log);
|
|
520
|
-
destroyHandlers.push(destroyMethodProxies);
|
|
521
|
-
clearTimeout(timeoutId);
|
|
522
|
-
isComplete = true;
|
|
523
|
-
resolve({
|
|
524
|
-
remoteProxy,
|
|
525
|
-
destroy
|
|
526
|
-
});
|
|
527
|
-
};
|
|
528
|
-
const sendSynMessage = () => {
|
|
529
|
-
const synMessage = {
|
|
530
|
-
namespace: namespace_default,
|
|
531
|
-
type: "SYN",
|
|
532
|
-
channel,
|
|
533
|
-
participantId
|
|
534
|
-
};
|
|
535
|
-
log == null ? void 0 : log(`Sending handshake SYN`, synMessage);
|
|
536
|
-
try {
|
|
537
|
-
messenger.sendMessage(synMessage);
|
|
538
|
-
} catch (error) {
|
|
539
|
-
reject(new PenpalError_default("TRANSMISSION_FAILED", error.message));
|
|
540
|
-
}
|
|
541
|
-
};
|
|
542
|
-
const handleSynMessage = (message) => {
|
|
543
|
-
log == null ? void 0 : log(`Received handshake SYN`, message);
|
|
544
|
-
if (message.participantId === remoteParticipantId && // TODO: Used for backward-compatibility. Remove in next major version.
|
|
545
|
-
remoteParticipantId !== DEPRECATED_PENPAL_PARTICIPANT_ID) {
|
|
546
|
-
return;
|
|
547
|
-
}
|
|
548
|
-
remoteParticipantId = message.participantId;
|
|
549
|
-
sendSynMessage();
|
|
550
|
-
const isHandshakeLeader = participantId > remoteParticipantId || // TODO: Used for backward-compatibility. Remove in next major version.
|
|
551
|
-
remoteParticipantId === DEPRECATED_PENPAL_PARTICIPANT_ID;
|
|
552
|
-
if (!isHandshakeLeader) {
|
|
553
|
-
return;
|
|
554
|
-
}
|
|
555
|
-
const ack1Message = {
|
|
556
|
-
namespace: namespace_default,
|
|
557
|
-
channel,
|
|
558
|
-
type: "ACK1",
|
|
559
|
-
methodPaths
|
|
560
|
-
};
|
|
561
|
-
log == null ? void 0 : log(`Sending handshake ACK1`, ack1Message);
|
|
562
|
-
try {
|
|
563
|
-
messenger.sendMessage(ack1Message);
|
|
564
|
-
} catch (error) {
|
|
565
|
-
reject(new PenpalError_default("TRANSMISSION_FAILED", error.message));
|
|
566
|
-
return;
|
|
567
|
-
}
|
|
568
|
-
};
|
|
569
|
-
const handleAck1Message = (message) => {
|
|
570
|
-
log == null ? void 0 : log(`Received handshake ACK1`, message);
|
|
571
|
-
const ack2Message = {
|
|
572
|
-
namespace: namespace_default,
|
|
573
|
-
channel,
|
|
574
|
-
type: "ACK2"
|
|
575
|
-
};
|
|
576
|
-
log == null ? void 0 : log(`Sending handshake ACK2`, ack2Message);
|
|
577
|
-
try {
|
|
578
|
-
messenger.sendMessage(ack2Message);
|
|
579
|
-
} catch (error) {
|
|
580
|
-
reject(new PenpalError_default("TRANSMISSION_FAILED", error.message));
|
|
581
|
-
return;
|
|
582
|
-
}
|
|
583
|
-
connectCallHandlerAndMethodProxies();
|
|
584
|
-
};
|
|
585
|
-
const handleAck2Message = (message) => {
|
|
586
|
-
log == null ? void 0 : log(`Received handshake ACK2`, message);
|
|
587
|
-
connectCallHandlerAndMethodProxies();
|
|
588
|
-
};
|
|
589
|
-
const handleMessage = (message) => {
|
|
590
|
-
if (isSynMessage(message)) {
|
|
591
|
-
handleSynMessage(message);
|
|
592
|
-
}
|
|
593
|
-
if (isAck1Message(message)) {
|
|
594
|
-
handleAck1Message(message);
|
|
595
|
-
}
|
|
596
|
-
if (isAck2Message(message)) {
|
|
597
|
-
handleAck2Message(message);
|
|
598
|
-
}
|
|
599
|
-
};
|
|
600
|
-
messenger.addMessageHandler(handleMessage);
|
|
601
|
-
destroyHandlers.push(() => messenger.removeMessageHandler(handleMessage));
|
|
602
|
-
sendSynMessage();
|
|
603
|
-
return promise;
|
|
604
|
-
};
|
|
605
|
-
var shakeHands_default = shakeHands;
|
|
606
|
-
var once = (fn) => {
|
|
607
|
-
let isCalled = false;
|
|
608
|
-
let result;
|
|
609
|
-
return (...args) => {
|
|
610
|
-
if (!isCalled) {
|
|
611
|
-
isCalled = true;
|
|
612
|
-
result = fn(...args);
|
|
102
|
+
// To be implemented by adapters
|
|
103
|
+
open(link) {
|
|
104
|
+
if (this.config.onOpen) {
|
|
105
|
+
this.config.onOpen();
|
|
613
106
|
}
|
|
614
|
-
return result;
|
|
615
|
-
};
|
|
616
|
-
};
|
|
617
|
-
var once_default = once;
|
|
618
|
-
var usedMessengers = /* @__PURE__ */ new WeakSet();
|
|
619
|
-
var connect = ({
|
|
620
|
-
messenger,
|
|
621
|
-
methods = {},
|
|
622
|
-
timeout,
|
|
623
|
-
channel,
|
|
624
|
-
log
|
|
625
|
-
}) => {
|
|
626
|
-
if (!messenger) {
|
|
627
|
-
throw new PenpalError_default("INVALID_ARGUMENT", "messenger must be defined");
|
|
628
107
|
}
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
"INVALID_ARGUMENT",
|
|
632
|
-
"A messenger can only be used for a single connection"
|
|
633
|
-
);
|
|
108
|
+
// To be implemented by adapters
|
|
109
|
+
destroy() {
|
|
634
110
|
}
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
const destroyConnection = once_default((notifyOtherParticipant) => {
|
|
638
|
-
if (notifyOtherParticipant) {
|
|
639
|
-
const destroyMessage = {
|
|
640
|
-
namespace: namespace_default,
|
|
641
|
-
channel,
|
|
642
|
-
type: "DESTROY"
|
|
643
|
-
};
|
|
644
|
-
try {
|
|
645
|
-
messenger.sendMessage(destroyMessage);
|
|
646
|
-
} catch (_) {
|
|
647
|
-
}
|
|
648
|
-
}
|
|
649
|
-
for (const connectionDestroyedHandler of connectionDestroyedHandlers) {
|
|
650
|
-
connectionDestroyedHandler();
|
|
651
|
-
}
|
|
652
|
-
log == null ? void 0 : log("Connection destroyed");
|
|
653
|
-
});
|
|
654
|
-
const validateReceivedMessage = (data) => {
|
|
655
|
-
return isMessage(data) && data.channel === channel;
|
|
656
|
-
};
|
|
657
|
-
const promise = (async () => {
|
|
658
|
-
try {
|
|
659
|
-
messenger.initialize({ log, validateReceivedMessage });
|
|
660
|
-
messenger.addMessageHandler((message) => {
|
|
661
|
-
if (isDestroyMessage(message)) {
|
|
662
|
-
destroyConnection(false);
|
|
663
|
-
}
|
|
664
|
-
});
|
|
665
|
-
const { remoteProxy, destroy } = await shakeHands_default({
|
|
666
|
-
messenger,
|
|
667
|
-
methods,
|
|
668
|
-
timeout,
|
|
669
|
-
channel,
|
|
670
|
-
log
|
|
671
|
-
});
|
|
672
|
-
connectionDestroyedHandlers.push(destroy);
|
|
673
|
-
return remoteProxy;
|
|
674
|
-
} catch (error) {
|
|
675
|
-
destroyConnection(true);
|
|
676
|
-
throw error;
|
|
677
|
-
}
|
|
678
|
-
})();
|
|
679
|
-
return {
|
|
680
|
-
promise,
|
|
681
|
-
// Why we don't reject the connection promise when consumer calls destroy():
|
|
682
|
-
// https://github.com/Aaronius/penpal/issues/51
|
|
683
|
-
destroy: () => {
|
|
684
|
-
destroyConnection(true);
|
|
685
|
-
}
|
|
686
|
-
};
|
|
687
|
-
};
|
|
688
|
-
var connect_default = connect;
|
|
689
|
-
var WindowMessenger = (_d = class {
|
|
690
|
-
constructor({ remoteWindow, allowedOrigins }) {
|
|
691
|
-
__privateAdd(this, _remoteWindow);
|
|
692
|
-
__privateAdd(this, _allowedOrigins);
|
|
693
|
-
__privateAdd(this, _log);
|
|
694
|
-
__privateAdd(this, _validateReceivedMessage);
|
|
695
|
-
__privateAdd(this, _concreteRemoteOrigin);
|
|
696
|
-
__privateAdd(this, _messageCallbacks, /* @__PURE__ */ new Set());
|
|
697
|
-
__privateAdd(this, _port);
|
|
698
|
-
// TODO: Used for backward-compatibility. Remove in next major version.
|
|
699
|
-
__privateAdd(this, _isChildUsingDeprecatedProtocol, false);
|
|
700
|
-
__publicField(this, "initialize", ({
|
|
701
|
-
log,
|
|
702
|
-
validateReceivedMessage
|
|
703
|
-
}) => {
|
|
704
|
-
__privateSet(this, _log, log);
|
|
705
|
-
__privateSet(this, _validateReceivedMessage, validateReceivedMessage);
|
|
706
|
-
window.addEventListener("message", __privateGet(this, _handleMessageFromRemoteWindow));
|
|
707
|
-
});
|
|
708
|
-
__publicField(this, "sendMessage", (message, transferables) => {
|
|
709
|
-
if (isSynMessage(message)) {
|
|
710
|
-
const originForSending = __privateGet(this, _getOriginForSendingMessage).call(this, message);
|
|
711
|
-
__privateGet(this, _remoteWindow).postMessage(message, {
|
|
712
|
-
targetOrigin: originForSending,
|
|
713
|
-
transfer: transferables
|
|
714
|
-
});
|
|
715
|
-
return;
|
|
716
|
-
}
|
|
717
|
-
if (isAck1Message(message) || // If the child is using a previous version of Penpal, we need to
|
|
718
|
-
// downgrade the message and send it through the window rather than
|
|
719
|
-
// the port because older versions of Penpal don't use MessagePorts.
|
|
720
|
-
__privateGet(this, _isChildUsingDeprecatedProtocol)) {
|
|
721
|
-
const payload = __privateGet(this, _isChildUsingDeprecatedProtocol) ? downgradeMessage(message) : message;
|
|
722
|
-
const originForSending = __privateGet(this, _getOriginForSendingMessage).call(this, message);
|
|
723
|
-
__privateGet(this, _remoteWindow).postMessage(payload, {
|
|
724
|
-
targetOrigin: originForSending,
|
|
725
|
-
transfer: transferables
|
|
726
|
-
});
|
|
727
|
-
return;
|
|
728
|
-
}
|
|
729
|
-
if (isAck2Message(message)) {
|
|
730
|
-
const { port1, port2 } = new MessageChannel();
|
|
731
|
-
__privateSet(this, _port, port1);
|
|
732
|
-
port1.addEventListener("message", __privateGet(this, _handleMessageFromPort));
|
|
733
|
-
port1.start();
|
|
734
|
-
const transferablesToSend = [port2, ...transferables || []];
|
|
735
|
-
const originForSending = __privateGet(this, _getOriginForSendingMessage).call(this, message);
|
|
736
|
-
__privateGet(this, _remoteWindow).postMessage(message, {
|
|
737
|
-
targetOrigin: originForSending,
|
|
738
|
-
transfer: transferablesToSend
|
|
739
|
-
});
|
|
740
|
-
return;
|
|
741
|
-
}
|
|
742
|
-
if (__privateGet(this, _port)) {
|
|
743
|
-
__privateGet(this, _port).postMessage(message, {
|
|
744
|
-
transfer: transferables
|
|
745
|
-
});
|
|
746
|
-
return;
|
|
747
|
-
}
|
|
748
|
-
throw new PenpalError_default(
|
|
749
|
-
"TRANSMISSION_FAILED",
|
|
750
|
-
"Cannot send message because the MessagePort is not connected"
|
|
751
|
-
);
|
|
752
|
-
});
|
|
753
|
-
__publicField(this, "addMessageHandler", (callback) => {
|
|
754
|
-
__privateGet(this, _messageCallbacks).add(callback);
|
|
755
|
-
});
|
|
756
|
-
__publicField(this, "removeMessageHandler", (callback) => {
|
|
757
|
-
__privateGet(this, _messageCallbacks).delete(callback);
|
|
758
|
-
});
|
|
759
|
-
__publicField(this, "destroy", () => {
|
|
760
|
-
window.removeEventListener("message", __privateGet(this, _handleMessageFromRemoteWindow));
|
|
761
|
-
__privateGet(this, _destroyPort).call(this);
|
|
762
|
-
__privateGet(this, _messageCallbacks).clear();
|
|
763
|
-
});
|
|
764
|
-
__privateAdd(this, _isAllowedOrigin, (origin) => {
|
|
765
|
-
return __privateGet(this, _allowedOrigins).some(
|
|
766
|
-
(allowedOrigin) => allowedOrigin instanceof RegExp ? allowedOrigin.test(origin) : allowedOrigin === origin || allowedOrigin === "*"
|
|
767
|
-
);
|
|
768
|
-
});
|
|
769
|
-
__privateAdd(this, _getOriginForSendingMessage, (message) => {
|
|
770
|
-
if (isSynMessage(message)) {
|
|
771
|
-
return "*";
|
|
772
|
-
}
|
|
773
|
-
if (!__privateGet(this, _concreteRemoteOrigin)) {
|
|
774
|
-
throw new PenpalError_default(
|
|
775
|
-
"TRANSMISSION_FAILED",
|
|
776
|
-
"Cannot send message because the remote origin is not established"
|
|
777
|
-
);
|
|
778
|
-
}
|
|
779
|
-
return __privateGet(this, _concreteRemoteOrigin) === "null" && __privateGet(this, _allowedOrigins).includes("*") ? "*" : __privateGet(this, _concreteRemoteOrigin);
|
|
780
|
-
});
|
|
781
|
-
__privateAdd(this, _destroyPort, () => {
|
|
782
|
-
var _a2, _b2;
|
|
783
|
-
(_a2 = __privateGet(this, _port)) == null ? void 0 : _a2.removeEventListener("message", __privateGet(this, _handleMessageFromPort));
|
|
784
|
-
(_b2 = __privateGet(this, _port)) == null ? void 0 : _b2.close();
|
|
785
|
-
__privateSet(this, _port, void 0);
|
|
786
|
-
});
|
|
787
|
-
__privateAdd(this, _handleMessageFromRemoteWindow, ({
|
|
788
|
-
source,
|
|
789
|
-
origin,
|
|
790
|
-
ports,
|
|
791
|
-
data
|
|
792
|
-
}) => {
|
|
793
|
-
var _a2, _b2, _c2, _d2, _e;
|
|
794
|
-
if (source !== __privateGet(this, _remoteWindow)) {
|
|
795
|
-
return;
|
|
796
|
-
}
|
|
797
|
-
if (isDeprecatedMessage(data)) {
|
|
798
|
-
(_a2 = __privateGet(this, _log)) == null ? void 0 : _a2.call(
|
|
799
|
-
this,
|
|
800
|
-
"Please upgrade the child window to the latest version of Penpal."
|
|
801
|
-
);
|
|
802
|
-
__privateSet(this, _isChildUsingDeprecatedProtocol, true);
|
|
803
|
-
try {
|
|
804
|
-
data = upgradeMessage(data);
|
|
805
|
-
} catch (error) {
|
|
806
|
-
(_b2 = __privateGet(this, _log)) == null ? void 0 : _b2.call(
|
|
807
|
-
this,
|
|
808
|
-
`Failed to translate deprecated message: ${error.message}`
|
|
809
|
-
);
|
|
810
|
-
return;
|
|
811
|
-
}
|
|
812
|
-
}
|
|
813
|
-
if (!((_c2 = __privateGet(this, _validateReceivedMessage)) == null ? void 0 : _c2.call(this, data))) {
|
|
814
|
-
return;
|
|
815
|
-
}
|
|
816
|
-
if (!__privateGet(this, _isAllowedOrigin).call(this, origin)) {
|
|
817
|
-
(_d2 = __privateGet(this, _log)) == null ? void 0 : _d2.call(
|
|
818
|
-
this,
|
|
819
|
-
`Received a message from origin \`${origin}\` which did not match allowed origins \`[${__privateGet(this, _allowedOrigins).join(", ")}]\``
|
|
820
|
-
);
|
|
821
|
-
return;
|
|
822
|
-
}
|
|
823
|
-
if (isSynMessage(data)) {
|
|
824
|
-
__privateGet(this, _destroyPort).call(this);
|
|
825
|
-
__privateSet(this, _concreteRemoteOrigin, origin);
|
|
826
|
-
}
|
|
827
|
-
if (isAck2Message(data) && // Previous versions of Penpal don't use MessagePorts and do all
|
|
828
|
-
// communication through the window.
|
|
829
|
-
!__privateGet(this, _isChildUsingDeprecatedProtocol)) {
|
|
830
|
-
__privateSet(this, _port, ports[0]);
|
|
831
|
-
if (!__privateGet(this, _port)) {
|
|
832
|
-
(_e = __privateGet(this, _log)) == null ? void 0 : _e.call(this, "Ignoring ACK2 because it did not include a MessagePort");
|
|
833
|
-
return;
|
|
834
|
-
}
|
|
835
|
-
__privateGet(this, _port).addEventListener("message", __privateGet(this, _handleMessageFromPort));
|
|
836
|
-
__privateGet(this, _port).start();
|
|
837
|
-
}
|
|
838
|
-
for (const callback of __privateGet(this, _messageCallbacks)) {
|
|
839
|
-
callback(data);
|
|
840
|
-
}
|
|
841
|
-
});
|
|
842
|
-
__privateAdd(this, _handleMessageFromPort, ({ data }) => {
|
|
843
|
-
var _a2;
|
|
844
|
-
if (!((_a2 = __privateGet(this, _validateReceivedMessage)) == null ? void 0 : _a2.call(this, data))) {
|
|
845
|
-
return;
|
|
846
|
-
}
|
|
847
|
-
for (const callback of __privateGet(this, _messageCallbacks)) {
|
|
848
|
-
callback(data);
|
|
849
|
-
}
|
|
850
|
-
});
|
|
851
|
-
if (!remoteWindow) {
|
|
852
|
-
throw new PenpalError_default("INVALID_ARGUMENT", "remoteWindow must be defined");
|
|
853
|
-
}
|
|
854
|
-
__privateSet(this, _remoteWindow, remoteWindow);
|
|
855
|
-
__privateSet(this, _allowedOrigins, (allowedOrigins == null ? void 0 : allowedOrigins.length) ? allowedOrigins : [window.origin]);
|
|
111
|
+
post(action, data = {}) {
|
|
112
|
+
this.sendMessage({ from: "SamanDesk", action, data });
|
|
856
113
|
}
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
frame2.addEventListener("load", () => {
|
|
863
|
-
this.connectChild();
|
|
114
|
+
run(action, data = {}) {
|
|
115
|
+
const id = ++this.promiseCount;
|
|
116
|
+
this.sendMessage({ from: "SamanDesk", action, data, id });
|
|
117
|
+
return new Promise((resolve) => {
|
|
118
|
+
this.runPromises[id] = resolve;
|
|
864
119
|
});
|
|
865
120
|
}
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
const frame2 = getFrame();
|
|
869
|
-
if (!frame2.contentWindow || !frame2.src) return;
|
|
870
|
-
(_a2 = this.connection) == null ? void 0 : _a2.destroy();
|
|
871
|
-
this.connection = connect_default({
|
|
872
|
-
messenger: new WindowMessenger_default({
|
|
873
|
-
remoteWindow: frame2.contentWindow,
|
|
874
|
-
allowedOrigins: [new URL(frame2.src, window.location.href).origin]
|
|
875
|
-
}),
|
|
876
|
-
methods: {
|
|
877
|
-
setToken: this.setToken.bind(this),
|
|
878
|
-
close: this.close.bind(this),
|
|
879
|
-
getConfig: this.getConfig.bind(this),
|
|
880
|
-
openLink: this.openLink.bind(this),
|
|
881
|
-
setGuestReadyEvent: this.setGuestReadyEvent.bind(this)
|
|
882
|
-
}
|
|
883
|
-
});
|
|
884
|
-
this.connection.promise.catch(() => {
|
|
885
|
-
});
|
|
886
|
-
}
|
|
887
|
-
/** توکن را از میزبان دریافت کرده و آن را ذخیره میکند. سپس به میزبان اعلام میکند که آمادهی ادامهی کار است */
|
|
888
|
-
setToken(data) {
|
|
889
|
-
setToken(data.token);
|
|
890
|
-
clearFrame();
|
|
891
|
-
window.dispatchEvent(getReadyEvent());
|
|
892
|
-
}
|
|
893
|
-
/** بستن کتابخانه */
|
|
894
|
-
close() {
|
|
895
|
-
clearFrame();
|
|
896
|
-
const backdrop2 = getBackdrop();
|
|
897
|
-
document.body.removeChild(backdrop2);
|
|
898
|
-
backdrop2.onclick = null;
|
|
899
|
-
document.body.removeChild(getFrame());
|
|
900
|
-
window.dispatchEvent(getCloseEvent());
|
|
901
|
-
}
|
|
902
|
-
/** اطلاعات کتابخانه را به بیرون اطلاع میدهد */
|
|
903
|
-
getConfig() {
|
|
904
|
-
const themeData = getTheme();
|
|
905
|
-
const languageData = getLanguage();
|
|
906
|
-
return { color: themeData.color, theme: themeData.theme, language: languageData.language };
|
|
907
|
-
}
|
|
908
|
-
/** لینک موردنظر را به وسیلهی تابع از پیش تعریفشده باز میکند */
|
|
909
|
-
openLink(data) {
|
|
910
|
-
getOpenLinkFn()(data.link);
|
|
911
|
-
}
|
|
912
|
-
setGuestReadyEvent() {
|
|
913
|
-
window.dispatchEvent(setGuestReadyEvent());
|
|
121
|
+
sendResponse(id, action, data) {
|
|
122
|
+
this.sendMessage({ from: "SamanDesk", action, data, id });
|
|
914
123
|
}
|
|
915
124
|
}
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
const frame2 = getFrame();
|
|
925
|
-
const backdrop2 = getBackdrop();
|
|
926
|
-
setTheme({
|
|
927
|
-
darkMode: config.theme.darkMode ?? "light",
|
|
928
|
-
color: config.theme.color ?? "default"
|
|
929
|
-
});
|
|
930
|
-
setLanguage(config.language ?? "fa");
|
|
931
|
-
setOpenLinkFn(config.linkHandler);
|
|
932
|
-
this.config = config;
|
|
933
|
-
if (verifiedToken) {
|
|
934
|
-
setFrameSrc(`${SITE_URL}/setup-interoperation/${verifiedToken}`);
|
|
935
|
-
frame2.width = "0";
|
|
936
|
-
frame2.style.width = "0";
|
|
937
|
-
} else {
|
|
938
|
-
this.setStyle();
|
|
939
|
-
setFrameSrc(`${SITE_URL}/guest-login/${config.workspaceID}`);
|
|
940
|
-
}
|
|
941
|
-
document.body.appendChild(backdrop2);
|
|
942
|
-
document.body.appendChild(frame2);
|
|
943
|
-
}
|
|
944
|
-
/**
|
|
945
|
-
* استایل مربوط به آیفریم را تنظیم میکند
|
|
946
|
-
*
|
|
947
|
-
* @param fullScreen - تمام صفحه باز شود یا خیر
|
|
948
|
-
*
|
|
949
|
-
*/
|
|
950
|
-
setStyle() {
|
|
951
|
-
var _a2, _b2, _c2, _d2;
|
|
952
|
-
const frame2 = getFrame();
|
|
953
|
-
const backdrop2 = getBackdrop();
|
|
954
|
-
frame2.style.position = "fixed";
|
|
955
|
-
frame2.style.zIndex = "1000";
|
|
956
|
-
const backdropStyles = {
|
|
125
|
+
function createSamanDeskWeb(config, options = {}) {
|
|
126
|
+
const frame = document.createElement("iframe");
|
|
127
|
+
const backdrop = document.createElement("div");
|
|
128
|
+
let isFrameAttached = false;
|
|
129
|
+
const core = new SamanDeskCore(config);
|
|
130
|
+
const applyStyles = () => {
|
|
131
|
+
var _a, _b, _c, _d;
|
|
132
|
+
Object.assign(backdrop.style, {
|
|
957
133
|
position: "fixed",
|
|
958
134
|
top: "0",
|
|
959
135
|
bottom: "0",
|
|
960
136
|
left: "0",
|
|
961
137
|
right: "0",
|
|
962
138
|
backgroundColor: "rgba(0,0,0,0.5)",
|
|
963
|
-
zIndex: "1000"
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
139
|
+
zIndex: "1000",
|
|
140
|
+
display: "none"
|
|
141
|
+
});
|
|
142
|
+
Object.assign(frame.style, {
|
|
143
|
+
position: "fixed",
|
|
144
|
+
zIndex: "1000",
|
|
145
|
+
border: "none",
|
|
146
|
+
display: "none"
|
|
147
|
+
});
|
|
148
|
+
if (options.fullScreen) {
|
|
149
|
+
const marginTopVal = ((_a = options.style) == null ? void 0 : _a.marginTop) ?? 0;
|
|
150
|
+
const marginBottomVal = ((_b = options.style) == null ? void 0 : _b.marginBottom) ?? 0;
|
|
969
151
|
const totalMargin = marginTopVal + marginBottomVal;
|
|
970
|
-
Object.assign(
|
|
971
|
-
bottom:
|
|
152
|
+
Object.assign(frame.style, {
|
|
153
|
+
bottom: `${marginBottomVal}px`,
|
|
972
154
|
left: "0",
|
|
973
|
-
top:
|
|
155
|
+
top: `${marginTopVal}px`,
|
|
974
156
|
right: "0",
|
|
975
157
|
width: "100%",
|
|
976
158
|
height: `calc(100% - ${totalMargin}px)`
|
|
977
159
|
});
|
|
978
160
|
} else {
|
|
979
|
-
Object.assign(
|
|
161
|
+
Object.assign(frame.style, {
|
|
980
162
|
top: "50%",
|
|
981
163
|
left: "50%",
|
|
982
164
|
transform: "translate(-50%, -50%)",
|
|
983
|
-
width: "100%",
|
|
165
|
+
width: ((_c = options.style) == null ? void 0 : _c.width) || "100%",
|
|
984
166
|
maxWidth: "500px",
|
|
985
167
|
boxShadow: "0px 0px 100px 0px rgba(0,0,0,0.48)",
|
|
986
168
|
borderRadius: "24px",
|
|
987
|
-
height: "100%",
|
|
169
|
+
height: ((_d = options.style) == null ? void 0 : _d.height) || "100%",
|
|
988
170
|
maxHeight: "660px"
|
|
989
171
|
});
|
|
990
172
|
}
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
173
|
+
};
|
|
174
|
+
const attachFrame = () => {
|
|
175
|
+
if (!isFrameAttached) {
|
|
176
|
+
applyStyles();
|
|
177
|
+
document.body.appendChild(backdrop);
|
|
178
|
+
document.body.appendChild(frame);
|
|
179
|
+
backdrop.onclick = () => webApi.close();
|
|
180
|
+
window.addEventListener("message", handleMessage);
|
|
181
|
+
isFrameAttached = true;
|
|
182
|
+
}
|
|
183
|
+
};
|
|
184
|
+
const detachFrame = () => {
|
|
185
|
+
if (isFrameAttached) {
|
|
186
|
+
document.body.removeChild(backdrop);
|
|
187
|
+
document.body.removeChild(frame);
|
|
188
|
+
window.removeEventListener("message", handleMessage);
|
|
189
|
+
isFrameAttached = false;
|
|
190
|
+
}
|
|
191
|
+
};
|
|
192
|
+
const show = (src) => {
|
|
193
|
+
attachFrame();
|
|
194
|
+
frame.src = src;
|
|
195
|
+
frame.style.display = "block";
|
|
196
|
+
if (!options.fullScreen) {
|
|
197
|
+
backdrop.style.display = "block";
|
|
198
|
+
}
|
|
199
|
+
if (config.onOpen) config.onOpen();
|
|
200
|
+
};
|
|
201
|
+
const hide = () => {
|
|
202
|
+
frame.src = "about:blank";
|
|
203
|
+
frame.style.display = "none";
|
|
204
|
+
backdrop.style.display = "none";
|
|
205
|
+
if (config.onClose) config.onClose();
|
|
206
|
+
};
|
|
207
|
+
const handleMessage = (event) => {
|
|
208
|
+
core.handleIncomingMessage(event.data);
|
|
209
|
+
};
|
|
210
|
+
core.sendMessage = (message) => {
|
|
211
|
+
if (frame.contentWindow) {
|
|
212
|
+
frame.contentWindow.postMessage(message, config.siteUrl || "*");
|
|
213
|
+
}
|
|
214
|
+
};
|
|
215
|
+
const webApi = {
|
|
216
|
+
open: (link) => {
|
|
217
|
+
show(core.getOpenUrl(link));
|
|
218
|
+
},
|
|
219
|
+
close: () => {
|
|
220
|
+
hide();
|
|
221
|
+
},
|
|
222
|
+
destroy: () => {
|
|
223
|
+
hide();
|
|
224
|
+
detachFrame();
|
|
225
|
+
}
|
|
226
|
+
};
|
|
227
|
+
const initialSrc = core.getInitialUrl();
|
|
228
|
+
frame.src = initialSrc;
|
|
229
|
+
if (!config.verifiedToken) {
|
|
230
|
+
show(initialSrc);
|
|
231
|
+
} else {
|
|
232
|
+
attachFrame();
|
|
233
|
+
frame.style.width = "0";
|
|
234
|
+
frame.style.height = "0";
|
|
235
|
+
frame.style.display = "block";
|
|
1005
236
|
}
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
237
|
+
return webApi;
|
|
238
|
+
}
|
|
239
|
+
function createSamanDeskReactNative(config, options) {
|
|
240
|
+
class SamanDeskCoreReactNative extends SamanDeskCore {
|
|
241
|
+
sendMessage(message) {
|
|
242
|
+
const script = `
|
|
243
|
+
window.dispatchEvent(new MessageEvent('message', {
|
|
244
|
+
data: ${JSON.stringify(message)}
|
|
245
|
+
}));
|
|
246
|
+
`;
|
|
247
|
+
options.injectJavaScript(script);
|
|
248
|
+
}
|
|
1012
249
|
}
|
|
250
|
+
const core = new SamanDeskCoreReactNative(config);
|
|
251
|
+
const updateState = (updater) => {
|
|
252
|
+
const newState = {
|
|
253
|
+
source: { uri: "" },
|
|
254
|
+
visible: false,
|
|
255
|
+
...updater(currentState)
|
|
256
|
+
};
|
|
257
|
+
currentState = newState;
|
|
258
|
+
options.onStateChange(currentState);
|
|
259
|
+
};
|
|
260
|
+
const initialUrl = core.getInitialUrl();
|
|
261
|
+
let currentState = {
|
|
262
|
+
source: { uri: initialUrl },
|
|
263
|
+
visible: !config.verifiedToken
|
|
264
|
+
};
|
|
265
|
+
const rnApi = {
|
|
266
|
+
getState: () => {
|
|
267
|
+
return currentState;
|
|
268
|
+
},
|
|
269
|
+
open: (link) => {
|
|
270
|
+
updateState((prev) => ({
|
|
271
|
+
...prev,
|
|
272
|
+
source: { uri: core.getOpenUrl(link) },
|
|
273
|
+
visible: true
|
|
274
|
+
}));
|
|
275
|
+
if (config.onOpen) config.onOpen();
|
|
276
|
+
},
|
|
277
|
+
close: () => {
|
|
278
|
+
updateState((prev) => ({
|
|
279
|
+
...prev,
|
|
280
|
+
visible: false,
|
|
281
|
+
source: { uri: "about:blank" }
|
|
282
|
+
}));
|
|
283
|
+
if (config.onClose) config.onClose();
|
|
284
|
+
},
|
|
285
|
+
destroy: () => {
|
|
286
|
+
rnApi.close();
|
|
287
|
+
},
|
|
288
|
+
getWebViewProps: () => ({
|
|
289
|
+
// source: currentState.source,
|
|
290
|
+
onMessage: (event) => {
|
|
291
|
+
try {
|
|
292
|
+
core.handleIncomingMessage(JSON.parse(event.nativeEvent.data));
|
|
293
|
+
} catch (error) {
|
|
294
|
+
console.error(
|
|
295
|
+
"[SamanDesk-RN] Error parsing incoming message:",
|
|
296
|
+
error
|
|
297
|
+
);
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
// onLoadEnd: () => {
|
|
301
|
+
// // Potentially useful for signaling when the webview has loaded initial content
|
|
302
|
+
// },
|
|
303
|
+
// javaScriptEnabled: true,
|
|
304
|
+
// originWhitelist: ["*"], // Be more specific in production
|
|
305
|
+
})
|
|
306
|
+
};
|
|
307
|
+
return rnApi;
|
|
1013
308
|
}
|
|
1014
309
|
export {
|
|
1015
|
-
|
|
310
|
+
createSamanDeskReactNative,
|
|
311
|
+
createSamanDeskWeb
|
|
1016
312
|
};
|