samandesk 1.2.0 → 2.0.0-beta1.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.
@@ -1,3 +1,14 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __typeError = (msg) => {
3
+ throw TypeError(msg);
4
+ };
5
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
6
+ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
7
+ var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg);
8
+ var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
9
+ var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
10
+ var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), setter ? setter.call(obj, value) : member.set(obj, value), value);
11
+ var _brand, _a, _b, _brand2, _c, _remoteWindow, _allowedOrigins, _log, _validateReceivedMessage, _concreteRemoteOrigin, _messageCallbacks, _port, _isChildUsingDeprecatedProtocol, _isAllowedOrigin, _getOriginForSendingMessage, _destroyPort, _handleMessageFromRemoteWindow, _handleMessageFromPort, _d;
1
12
  let token;
2
13
  const frame = document.createElement("iframe");
3
14
  let theme;
@@ -5,13 +16,6 @@ let color;
5
16
  let language;
6
17
  let linkHandler = (link) => window.open(link, "_blank", "noopener");
7
18
  const backdrop = document.createElement("div");
8
- const run = {
9
- count: 0,
10
- promises: {}
11
- };
12
- function getRun() {
13
- return run;
14
- }
15
19
  function setToken(newToken) {
16
20
  token = newToken;
17
21
  }
@@ -65,41 +69,824 @@ function getCloseEvent() {
65
69
  function setGuestReadyEvent() {
66
70
  return guestReadyEvent;
67
71
  }
68
- function handleEvents(interoperation) {
69
- window.addEventListener("message", (event) => {
70
- if (!event.data.from || event.data.from !== "SamanDesk") return;
71
- let handledByInterOperation = false;
72
- console.log(`message from (${event.origin})`, event);
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;
78
+ }
79
+ };
80
+ var PenpalError_default = PenpalError;
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;
109
+ }
110
+ }, _brand = new WeakMap(), _a);
111
+ var Reply_default = Reply;
112
+ var namespace_default = "penpal";
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
+ );
150
+ }
151
+ }
152
+ return methodPaths;
153
+ };
154
+ var getMethodAtMethodPath = (methodPath, methods) => {
155
+ const result = methodPath.reduce(
156
+ (acc, pathSegment) => {
157
+ return isObject(acc) ? acc[pathSegment] : void 0;
158
+ },
159
+ methods
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) {
178
+ return;
179
+ }
180
+ if (!isCallMessage(message)) {
181
+ return;
182
+ }
183
+ log == null ? void 0 : log(`Received ${formatMethodPath(message.methodPath)}() call`, message);
184
+ const { methodPath, args, id: callId } = message;
185
+ let replyMessage;
186
+ let transferables;
187
+ try {
188
+ const method = getMethodAtMethodPath(methodPath, methods);
189
+ if (!method) {
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;
199
+ }
200
+ replyMessage = {
201
+ namespace: namespace_default,
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
+ }
73
213
  try {
74
- interoperation[event.data.action](event.data);
75
- handledByInterOperation = true;
76
- } catch (err) {
77
- console.error("error while run event action");
78
- }
79
- const data = event.data;
80
- const id = data.id;
81
- const run2 = getRun();
82
- if (id in run2.promises && run2.promises[id]) {
83
- run2.promises[id](data);
84
- delete run2.promises[id];
85
- } else if (!handledByInterOperation) {
86
- console.error("Message from outside of frame is invalid");
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);
221
+ }
222
+ throw error;
223
+ }
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
+ }
247
+ }, _brand2 = new WeakMap(), _c);
248
+ var CallOptions_default = CallOptions;
249
+ var methodsToTreatAsNative = /* @__PURE__ */ new Set(["apply", "call", "bind"]);
250
+ var createRemoteProxy = (callback, log, path = []) => {
251
+ return new Proxy(
252
+ path.length ? () => {
253
+ } : /* @__PURE__ */ Object.create(null),
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
+ }
87
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;
289
+ }
290
+ replyHandlers.delete(callId);
291
+ log == null ? void 0 : log(
292
+ `Received ${formatMethodPath(replyHandler.methodPath)}() call`,
293
+ message
294
+ );
295
+ if (isError) {
296
+ replyHandler.reject(
297
+ isSerializedErrorInstance ? deserializeError(value) : value
298
+ );
299
+ } else {
300
+ replyHandler.resolve(value);
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));
350
+ }
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;
88
365
  });
89
- }
90
- function resolveRun(id, data, action) {
91
- var _a;
92
- const postData = { from: "SamanDesk", action, data, id };
93
- const frame2 = getFrame();
94
- (_a = frame2.contentWindow) == null ? void 0 : _a.postMessage(postData, "*");
95
- }
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
+ }
385
+ };
386
+ var getUnexpectedMessageError = (message) => {
387
+ return new PenpalError_default(
388
+ "TRANSMISSION_FAILED",
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
+ };
444
+ }
445
+ }
446
+ throw getUnexpectedMessageError(message);
447
+ };
448
+ var downgradeMessage = (message) => {
449
+ if (isAck1Message(message)) {
450
+ return {
451
+ penpal: "synAck",
452
+ methodNames: message.methodPaths.map(downgradeMethodPath)
453
+ };
454
+ }
455
+ if (isCallMessage(message)) {
456
+ return {
457
+ penpal: "call",
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
+ };
463
+ }
464
+ if (isReplyMessage(message)) {
465
+ if (message.isError) {
466
+ return {
467
+ penpal: "reply",
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
+ };
484
+ }
485
+ }
486
+ throw getUnexpectedMessageError(message);
487
+ };
488
+ var shakeHands = ({
489
+ messenger,
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);
613
+ }
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
+ }
629
+ if (usedMessengers.has(messenger)) {
630
+ throw new PenpalError_default(
631
+ "INVALID_ARGUMENT",
632
+ "A messenger can only be used for a single connection"
633
+ );
634
+ }
635
+ usedMessengers.add(messenger);
636
+ const connectionDestroyedHandlers = [messenger.destroy];
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]);
856
+ }
857
+ }, _remoteWindow = new WeakMap(), _allowedOrigins = new WeakMap(), _log = new WeakMap(), _validateReceivedMessage = new WeakMap(), _concreteRemoteOrigin = new WeakMap(), _messageCallbacks = new WeakMap(), _port = new WeakMap(), _isChildUsingDeprecatedProtocol = new WeakMap(), _isAllowedOrigin = new WeakMap(), _getOriginForSendingMessage = new WeakMap(), _destroyPort = new WeakMap(), _handleMessageFromRemoteWindow = new WeakMap(), _handleMessageFromPort = new WeakMap(), _d);
858
+ var WindowMessenger_default = WindowMessenger;
96
859
  class InterOperation {
97
860
  async init() {
98
- handleEvents(this);
861
+ const frame2 = getFrame();
862
+ frame2.addEventListener("load", () => {
863
+ this.connectChild();
864
+ });
865
+ }
866
+ connectChild() {
867
+ var _a2;
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
+ });
99
886
  }
100
887
  /** توکن را از میزبان دریافت کرده و آن را ذخیره می‌کند. سپس به میزبان اعلام می‌کند که آماده‌ی ادامه‌ی کار است */
101
888
  setToken(data) {
102
- setToken(data.data.token);
889
+ setToken(data.token);
103
890
  clearFrame();
104
891
  window.dispatchEvent(getReadyEvent());
105
892
  }
@@ -113,20 +900,20 @@ class InterOperation {
113
900
  window.dispatchEvent(getCloseEvent());
114
901
  }
115
902
  /** اطلاعات کتابخانه را به بیرون اطلاع می‌دهد */
116
- getConfig(data) {
903
+ getConfig() {
117
904
  const themeData = getTheme();
118
905
  const languageData = getLanguage();
119
- resolveRun(data.id, { color: themeData.color, theme: themeData.theme, language: languageData.language }, data.action);
906
+ return { color: themeData.color, theme: themeData.theme, language: languageData.language };
120
907
  }
121
908
  /** لینک موردنظر را به وسیله‌ی تابع از پیش تعریف‌شده باز می‌کند */
122
909
  openLink(data) {
123
- getOpenLinkFn()(data.data.link);
910
+ getOpenLinkFn()(data.link);
124
911
  }
125
912
  setGuestReadyEvent() {
126
913
  window.dispatchEvent(setGuestReadyEvent());
127
914
  }
128
915
  }
129
- const SITE_URL = "https://samandesk.com";
916
+ const SITE_URL = "http://localhost:2525";
130
917
  class SamanDesk {
131
918
  /**
132
919
  * ⁧این تابع در ابتدا مقدار verifiedToken را دریافت کرده و سپس مقدار token‌ را دریافت و سپس آن را ذخیره می‌کند
@@ -161,7 +948,7 @@ class SamanDesk {
161
948
  *
162
949
  */
163
950
  setStyle() {
164
- var _a, _b, _c, _d;
951
+ var _a2, _b2, _c2, _d2;
165
952
  const frame2 = getFrame();
166
953
  const backdrop2 = getBackdrop();
167
954
  frame2.style.position = "fixed";
@@ -177,13 +964,13 @@ class SamanDesk {
177
964
  };
178
965
  Object.assign(backdrop2.style, backdropStyles);
179
966
  if (this.config.fullScreen) {
180
- const marginTopVal = ((_a = this.config.style) == null ? void 0 : _a.marginTop) ?? 0;
181
- const marginBottomVal = ((_b = this.config.style) == null ? void 0 : _b.marginBottom) ?? 0;
967
+ const marginTopVal = ((_a2 = this.config.style) == null ? void 0 : _a2.marginTop) ?? 0;
968
+ const marginBottomVal = ((_b2 = this.config.style) == null ? void 0 : _b2.marginBottom) ?? 0;
182
969
  const totalMargin = marginTopVal + marginBottomVal;
183
970
  Object.assign(frame2.style, {
184
- bottom: ((_c = this.config.style) == null ? void 0 : _c.marginBottom) ? `${this.config.style.marginBottom.toString()}px` : "0",
971
+ bottom: ((_c2 = this.config.style) == null ? void 0 : _c2.marginBottom) ? `${this.config.style.marginBottom.toString()}px` : "0",
185
972
  left: "0",
186
- top: ((_d = this.config.style) == null ? void 0 : _d.marginTop) ? `${this.config.style.marginTop.toString()}px` : "0",
973
+ top: ((_d2 = this.config.style) == null ? void 0 : _d2.marginTop) ? `${this.config.style.marginTop.toString()}px` : "0",
187
974
  right: "0",
188
975
  width: "100%",
189
976
  height: `calc(100% - ${totalMargin}px)`
@@ -220,8 +1007,8 @@ class SamanDesk {
220
1007
  * بستن کتابخانه
221
1008
  */
222
1009
  close() {
223
- var _a;
224
- (_a = this.interoperation) == null ? void 0 : _a.close();
1010
+ var _a2;
1011
+ (_a2 = this.interoperation) == null ? void 0 : _a2.close();
225
1012
  }
226
1013
  }
227
1014
  export {
@@ -1 +1 @@
1
- !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).SamanDesk={})}(this,(function(e){"use strict";let t;const o=document.createElement("iframe");let n,i,s,a=e=>window.open(e,"_blank","noopener");const d=document.createElement("div"),l={count:0,promises:{}};function r(){o.src=""}function c(e){o.src=e}function p(){return o}function m(){return d}const g=new Event("ready"),h=new Event("open"),f=new Event("close"),u=new Event("guest-ready");function y(e){window.addEventListener("message",(t=>{if(!t.data.from||"SamanDesk"!==t.data.from)return;let o=!1;console.log(`message from (${t.origin})`,t);try{e[t.data.action](t.data),o=!0}catch(a){console.error("error while run event action")}const n=t.data,i=n.id,s=l;i in s.promises&&s.promises[i]?(s.promises[i](n),delete s.promises[i]):o||console.error("Message from outside of frame is invalid")}))}class v{async init(){y(this)}setToken(e){var o;o=e.data.token,t=o,r(),window.dispatchEvent(g)}close(){r();const e=m();document.body.removeChild(e),e.onclick=null,document.body.removeChild(p()),window.dispatchEvent(f)}getConfig(e){const t={theme:n,color:i},o={language:s};!function(e,t,o){var n;const i={from:"SamanDesk",action:o,data:t,id:e};null==(n=p().contentWindow)||n.postMessage(i,"*")}(e.id,{color:t.color,theme:t.theme,language:o.language},e.action)}openLink(e){a(e.data.link)}setGuestReadyEvent(){window.dispatchEvent(u)}}const w="https://samandesk.com";e.SamanDesk=class{async init(e,t){this.interoperation=new v,this.interoperation.init();const o=p(),d=m();var l,r,g;l={darkMode:e.theme.darkMode??"light",color:e.theme.color??"default"},n=l.darkMode,i=l.color,r=e.language??"fa",s=r,(g=e.linkHandler)&&(a=g),this.config=e,t?(c(`${w}/setup-interoperation/${t}`),o.width="0",o.style.width="0"):(this.setStyle(),c(`${w}/guest-login/${e.workspaceID}`)),document.body.appendChild(d),document.body.appendChild(o)}setStyle(){var e,t,o,n;const i=p(),s=m();i.style.position="fixed",i.style.zIndex="1000";if(Object.assign(s.style,{position:"fixed",top:"0",bottom:"0",left:"0",right:"0",backgroundColor:"rgba(0,0,0,0.5)",zIndex:"1000"}),this.config.fullScreen){const s=((null==(e=this.config.style)?void 0:e.marginTop)??0)+((null==(t=this.config.style)?void 0:t.marginBottom)??0);Object.assign(i.style,{bottom:(null==(o=this.config.style)?void 0:o.marginBottom)?`${this.config.style.marginBottom.toString()}px`:"0",left:"0",top:(null==(n=this.config.style)?void 0:n.marginTop)?`${this.config.style.marginTop.toString()}px`:"0",right:"0",width:"100%",height:`calc(100% - ${s}px)`})}else Object.assign(i.style,{top:"50%",left:"50%",transform:"translate(-50%, -50%)",width:"100%",maxWidth:"500px",boxShadow:"0px 0px 100px 0px rgba(0,0,0,0.48)",borderRadius:"24px",height:"100%",maxHeight:"660px"});document.body.appendChild(s),document.body.appendChild(i),s.onclick=()=>{this.close()}}open(e){const o=e||`${w}/department-selection?token=${t}`;this.setStyle(),c(o),window.dispatchEvent(h)}close(){var e;null==(e=this.interoperation)||e.close()}},Object.defineProperty(e,Symbol.toStringTag,{value:"Module"})}));
1
+ !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).SamanDesk={})}(this,(function(e){"use strict";var t,n,s,a,i,o,r,l,d,c,h,u,p,m,g,f,y,w,v,M=Object.defineProperty,E=e=>{throw TypeError(e)},S=(e,t,n)=>((e,t,n)=>t in e?M(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n)(e,"symbol"!=typeof t?t+"":t,n),b=(e,t,n)=>t.has(e)||E("Cannot "+n),I=(e,t,n)=>(b(e,t,"read from private field"),n?n.call(e):t.get(e)),k=(e,t,n)=>t.has(e)?E("Cannot add the same private member more than once"):t instanceof WeakSet?t.add(e):t.set(e,n),C=(e,t,n,s)=>(b(e,t,"write to private field"),s?s.call(e,n):t.set(e,n),n);let A;const N=document.createElement("iframe");let T,R,O,L=e=>window.open(e,"_blank","noopener");const P=document.createElement("div");function x(){N.src=""}function W(e){N.src=e}function $(){return N}function D(){return P}const j=new Event("ready"),_=new Event("open"),H=new Event("close"),Y=new Event("guest-ready");var V=class extends Error{constructor(e,t){super(t),S(this,"code"),this.name="PenpalError",this.code=e}},F=e=>({name:e.name,message:e.message,stack:e.stack,penpalCode:e instanceof V?e.code:void 0}),K=Symbol("Reply"),U=(n=class{constructor(e,n){S(this,"value"),S(this,"transferables"),k(this,t,K),this.value=e,this.transferables=null==n?void 0:n.transferables}},t=new WeakMap,n),z="penpal",G=e=>"object"==typeof e&&null!==e,B=e=>"function"==typeof e,J=e=>"SYN"===e.type,X=e=>"ACK1"===e.type,q=e=>"ACK2"===e.type,Q=e=>"CALL"===e.type,Z=e=>"REPLY"===e.type,ee=(e,t=[])=>{const n=[];for(const s of Object.keys(e)){const a=e[s];B(a)?n.push([...t,s]):G(a)&&n.push(...ee(a,[...t,s]))}return n},te=e=>e.join("."),ne=(e,t,n)=>({namespace:z,channel:e,type:"REPLY",callId:t,isError:!0,...n instanceof Error?{value:F(n),isSerializedErrorInstance:!0}:{value:n}}),se=(e,t,n,s)=>{let a=!1;const i=async i=>{if(a)return;if(!Q(i))return;null==s||s(`Received ${te(i.methodPath)}() call`,i);const{methodPath:o,args:r,id:l}=i;let d,c;try{const e=((e,t)=>{const n=e.reduce(((e,t)=>G(e)?e[t]:void 0),t);return B(n)?n:void 0})(o,t);if(!e)throw new V("METHOD_NOT_FOUND",`Method \`${te(o)}\` is not found.`);let s=await e(...r);s instanceof U&&(c=s.transferables,s=await s.value),d={namespace:z,channel:n,type:"REPLY",callId:l,value:s}}catch(h){d=ne(n,l,h)}if(!a)try{null==s||s(`Sending ${te(o)}() reply`,d),e.sendMessage(d,c)}catch(h){throw"DataCloneError"===h.name&&(d=ne(n,l,h),null==s||s(`Sending ${te(o)}() reply`,d),e.sendMessage(d)),h}};return e.addMessageHandler(i),()=>{a=!0,e.removeMessageHandler(i)}},ae=(null==(s=crypto.randomUUID)?void 0:s.bind(crypto))??(()=>new Array(4).fill(0).map((()=>Math.floor(Math.random()*Number.MAX_SAFE_INTEGER).toString(16))).join("-")),ie=Symbol("CallOptions"),oe=(i=class{constructor(e){S(this,"transferables"),S(this,"timeout"),k(this,a,ie),this.transferables=null==e?void 0:e.transferables,this.timeout=null==e?void 0:e.timeout}},a=new WeakMap,i),re=new Set(["apply","call","bind"]),le=(e,t,n=[])=>new Proxy(n.length?()=>{}:Object.create(null),{get(s,a){if("then"!==a)return n.length&&re.has(a)?Reflect.get(s,a):le(e,t,[...n,a])},apply:(t,s,a)=>e(n,a)}),de=e=>new V("CONNECTION_DESTROYED",`Method call ${te(e)}() failed due to destroyed connection`),ce=(e,t,n)=>{let s=!1;const a=new Map,i=e=>{if(!Z(e))return;const{callId:t,value:s,isError:i,isSerializedErrorInstance:o}=e,r=a.get(t);r&&(a.delete(t),null==n||n(`Received ${te(r.methodPath)}() call`,e),i?r.reject(o?(({name:e,message:t,stack:n,penpalCode:s})=>{const a=s?new V(s,t):new Error(t);return a.name=e,a.stack=n,a})(s):s):r.resolve(s))};e.addMessageHandler(i);return{remoteProxy:le(((i,o)=>{if(s)throw de(i);const r=ae(),l=o[o.length-1],d=l instanceof oe,{timeout:c,transferables:h}=d?l:{},u=d?o.slice(0,-1):o;return new Promise(((s,o)=>{const l=void 0!==c?window.setTimeout((()=>{a.delete(r),o(new V("METHOD_CALL_TIMEOUT",`Method call ${te(i)}() timed out after ${c}ms`))}),c):void 0;a.set(r,{methodPath:i,resolve:s,reject:o,timeoutId:l});try{const s={namespace:z,channel:t,type:"CALL",id:r,methodPath:i,args:u};null==n||n(`Sending ${te(i)}() call`,s),e.sendMessage(s,h)}catch(d){o(new V("TRANSMISSION_FAILED",d.message))}}))}),n),destroy:()=>{s=!0,e.removeMessageHandler(i);for(const{methodPath:e,reject:t,timeoutId:n}of a.values())clearTimeout(n),t(de(e));a.clear()}}},he=()=>{let e,t;return{promise:new Promise(((n,s)=>{e=n,t=s})),resolve:e,reject:t}},ue="deprecated-penpal",pe=e=>e.join("."),me=e=>new V("TRANSMISSION_FAILED",`Unexpected message to translate: ${(e=>{try{return JSON.stringify(e)}catch(t){return String(e)}})(e)}`),ge=({messenger:e,methods:t,timeout:n,channel:s,log:a})=>{const i=ae();let o;const r=[];let l=!1;const d=ee(t),{promise:c,resolve:h,reject:u}=he(),p=void 0!==n?setTimeout((()=>{u(new V("CONNECTION_TIMEOUT",`Connection timed out after ${n}ms`))}),n):void 0,m=()=>{for(const e of r)e()},g=()=>{if(l)return;r.push(se(e,t,s,a));const{remoteProxy:n,destroy:i}=ce(e,s,a);r.push(i),clearTimeout(p),l=!0,h({remoteProxy:n,destroy:m})},f=()=>{const t={namespace:z,type:"SYN",channel:s,participantId:i};null==a||a("Sending handshake SYN",t);try{e.sendMessage(t)}catch(n){u(new V("TRANSMISSION_FAILED",n.message))}},y=t=>{J(t)&&(t=>{if(null==a||a("Received handshake SYN",t),t.participantId===o&&o!==ue)return;if(o=t.participantId,f(),!(i>o||o===ue))return;const n={namespace:z,channel:s,type:"ACK1",methodPaths:d};null==a||a("Sending handshake ACK1",n);try{e.sendMessage(n)}catch(r){return void u(new V("TRANSMISSION_FAILED",r.message))}})(t),X(t)&&(t=>{null==a||a("Received handshake ACK1",t);const n={namespace:z,channel:s,type:"ACK2"};null==a||a("Sending handshake ACK2",n);try{e.sendMessage(n)}catch(i){return void u(new V("TRANSMISSION_FAILED",i.message))}g()})(t),q(t)&&(e=>{null==a||a("Received handshake ACK2",e),g()})(t)};return e.addMessageHandler(y),r.push((()=>e.removeMessageHandler(y))),f(),c},fe=e=>{let t,n=!1;return(...s)=>(n||(n=!0,t=e(...s)),t)},ye=new WeakSet,we=({messenger:e,methods:t={},timeout:n,channel:s,log:a})=>{if(!e)throw new V("INVALID_ARGUMENT","messenger must be defined");if(ye.has(e))throw new V("INVALID_ARGUMENT","A messenger can only be used for a single connection");ye.add(e);const i=[e.destroy],o=fe((t=>{if(t){const t={namespace:z,channel:s,type:"DESTROY"};try{e.sendMessage(t)}catch(n){}}for(const e of i)e();null==a||a("Connection destroyed")})),r=e=>(e=>G(e)&&e.namespace===z)(e)&&e.channel===s;return{promise:(async()=>{try{e.initialize({log:a,validateReceivedMessage:r}),e.addMessageHandler((e=>{(e=>"DESTROY"===e.type)(e)&&o(!1)}));const{remoteProxy:l,destroy:d}=await ge({messenger:e,methods:t,timeout:n,channel:s,log:a});return i.push(d),l}catch(l){throw o(!0),l}})(),destroy:()=>{o(!0)}}},ve=(v=class{constructor({remoteWindow:e,allowedOrigins:t}){if(k(this,o),k(this,r),k(this,l),k(this,d),k(this,c),k(this,h,new Set),k(this,u),k(this,p,!1),S(this,"initialize",(({log:e,validateReceivedMessage:t})=>{C(this,l,e),C(this,d,t),window.addEventListener("message",I(this,y))})),S(this,"sendMessage",((e,t)=>{if(J(e)){const n=I(this,g).call(this,e);I(this,o).postMessage(e,{targetOrigin:n,transfer:t})}else if(X(e)||I(this,p)){const n=I(this,p)?(e=>{if(X(e))return{penpal:"synAck",methodNames:e.methodPaths.map(pe)};if(Q(e))return{penpal:"call",id:e.id,methodName:pe(e.methodPath),args:e.args};if(Z(e))return e.isError?{penpal:"reply",id:e.callId,resolution:"rejected",...e.isSerializedErrorInstance?{returnValue:e.value,returnValueIsError:!0}:{returnValue:e.value}}:{penpal:"reply",id:e.callId,resolution:"fulfilled",returnValue:e.value};throw me(e)})(e):e,s=I(this,g).call(this,e);I(this,o).postMessage(n,{targetOrigin:s,transfer:t})}else if(q(e)){const{port1:n,port2:s}=new MessageChannel;C(this,u,n),n.addEventListener("message",I(this,w)),n.start();const a=[s,...t||[]],i=I(this,g).call(this,e);I(this,o).postMessage(e,{targetOrigin:i,transfer:a})}else{if(!I(this,u))throw new V("TRANSMISSION_FAILED","Cannot send message because the MessagePort is not connected");I(this,u).postMessage(e,{transfer:t})}})),S(this,"addMessageHandler",(e=>{I(this,h).add(e)})),S(this,"removeMessageHandler",(e=>{I(this,h).delete(e)})),S(this,"destroy",(()=>{window.removeEventListener("message",I(this,y)),I(this,f).call(this),I(this,h).clear()})),k(this,m,(e=>I(this,r).some((t=>t instanceof RegExp?t.test(e):t===e||"*"===t)))),k(this,g,(e=>{if(J(e))return"*";if(!I(this,c))throw new V("TRANSMISSION_FAILED","Cannot send message because the remote origin is not established");return"null"===I(this,c)&&I(this,r).includes("*")?"*":I(this,c)})),k(this,f,(()=>{var e,t;null==(e=I(this,u))||e.removeEventListener("message",I(this,w)),null==(t=I(this,u))||t.close(),C(this,u,void 0)})),k(this,y,(({source:e,origin:t,ports:n,data:s})=>{var a,i,g,y,v;if(e===I(this,o)){if((e=>G(e)&&"penpal"in e)(s)){null==(a=I(this,l))||a.call(this,"Please upgrade the child window to the latest version of Penpal."),C(this,p,!0);try{s=(e=>{if("syn"===e.penpal)return{namespace:z,channel:void 0,type:"SYN",participantId:ue};if("ack"===e.penpal)return{namespace:z,channel:void 0,type:"ACK2"};if("call"===e.penpal)return{namespace:z,channel:void 0,type:"CALL",id:e.id,methodPath:(t=e.methodName,t.split(".")),args:e.args};var t;if("reply"===e.penpal)return"fulfilled"===e.resolution?{namespace:z,channel:void 0,type:"REPLY",callId:e.id,value:e.returnValue}:{namespace:z,channel:void 0,type:"REPLY",callId:e.id,isError:!0,...e.returnValueIsError?{value:e.returnValue,isSerializedErrorInstance:!0}:{value:e.returnValue}};throw me(e)})(s)}catch(M){return void(null==(i=I(this,l))||i.call(this,`Failed to translate deprecated message: ${M.message}`))}}if(null==(g=I(this,d))?void 0:g.call(this,s))if(I(this,m).call(this,t)){if(J(s)&&(I(this,f).call(this),C(this,c,t)),q(s)&&!I(this,p)){if(C(this,u,n[0]),!I(this,u))return void(null==(v=I(this,l))||v.call(this,"Ignoring ACK2 because it did not include a MessagePort"));I(this,u).addEventListener("message",I(this,w)),I(this,u).start()}for(const e of I(this,h))e(s)}else null==(y=I(this,l))||y.call(this,`Received a message from origin \`${t}\` which did not match allowed origins \`[${I(this,r).join(", ")}]\``)}})),k(this,w,(({data:e})=>{var t;if(null==(t=I(this,d))?void 0:t.call(this,e))for(const n of I(this,h))n(e)})),!e)throw new V("INVALID_ARGUMENT","remoteWindow must be defined");C(this,o,e),C(this,r,(null==t?void 0:t.length)?t:[window.origin])}},o=new WeakMap,r=new WeakMap,l=new WeakMap,d=new WeakMap,c=new WeakMap,h=new WeakMap,u=new WeakMap,p=new WeakMap,m=new WeakMap,g=new WeakMap,f=new WeakMap,y=new WeakMap,w=new WeakMap,v);class Me{async init(){$().addEventListener("load",(()=>{this.connectChild()}))}connectChild(){var e;const t=$();t.contentWindow&&t.src&&(null==(e=this.connection)||e.destroy(),this.connection=we({messenger:new ve({remoteWindow:t.contentWindow,allowedOrigins:[new URL(t.src,window.location.href).origin]}),methods:{setToken:this.setToken.bind(this),close:this.close.bind(this),getConfig:this.getConfig.bind(this),openLink:this.openLink.bind(this),setGuestReadyEvent:this.setGuestReadyEvent.bind(this)}}),this.connection.promise.catch((()=>{})))}setToken(e){var t;t=e.token,A=t,x(),window.dispatchEvent(j)}close(){x();const e=D();document.body.removeChild(e),e.onclick=null,document.body.removeChild($()),window.dispatchEvent(H)}getConfig(){const e={theme:T,color:R};return{color:e.color,theme:e.theme,language:{language:O}.language}}openLink(e){L(e.link)}setGuestReadyEvent(){window.dispatchEvent(Y)}}const Ee="http://localhost:2525";e.SamanDesk=class{async init(e,t){this.interoperation=new Me,this.interoperation.init();const n=$(),s=D();var a,i,o;a={darkMode:e.theme.darkMode??"light",color:e.theme.color??"default"},T=a.darkMode,R=a.color,i=e.language??"fa",O=i,(o=e.linkHandler)&&(L=o),this.config=e,t?(W(`${Ee}/setup-interoperation/${t}`),n.width="0",n.style.width="0"):(this.setStyle(),W(`${Ee}/guest-login/${e.workspaceID}`)),document.body.appendChild(s),document.body.appendChild(n)}setStyle(){var e,t,n,s;const a=$(),i=D();a.style.position="fixed",a.style.zIndex="1000";if(Object.assign(i.style,{position:"fixed",top:"0",bottom:"0",left:"0",right:"0",backgroundColor:"rgba(0,0,0,0.5)",zIndex:"1000"}),this.config.fullScreen){const i=((null==(e=this.config.style)?void 0:e.marginTop)??0)+((null==(t=this.config.style)?void 0:t.marginBottom)??0);Object.assign(a.style,{bottom:(null==(n=this.config.style)?void 0:n.marginBottom)?`${this.config.style.marginBottom.toString()}px`:"0",left:"0",top:(null==(s=this.config.style)?void 0:s.marginTop)?`${this.config.style.marginTop.toString()}px`:"0",right:"0",width:"100%",height:`calc(100% - ${i}px)`})}else Object.assign(a.style,{top:"50%",left:"50%",transform:"translate(-50%, -50%)",width:"100%",maxWidth:"500px",boxShadow:"0px 0px 100px 0px rgba(0,0,0,0.48)",borderRadius:"24px",height:"100%",maxHeight:"660px"});document.body.appendChild(i),document.body.appendChild(a),i.onclick=()=>{this.close()}}open(e){const t=e||`${Ee}/department-selection?token=${A}`;this.setStyle(),W(t),window.dispatchEvent(_)}close(){var e;null==(e=this.interoperation)||e.close()}},Object.defineProperty(e,Symbol.toStringTag,{value:"Module"})}));
@@ -13,18 +13,6 @@ export type GuestData = {
13
13
  verifyToken: string;
14
14
  workspaceID: string;
15
15
  };
16
- type PromiseMap = {
17
- [key: number]: (data: any) => void;
18
- };
19
- /** آبجکت پرامیس‌های منتظر اجرا */
20
- export declare function getRun(): {
21
- count: number;
22
- promises: PromiseMap;
23
- };
24
- /** تنظیم تعداد پرامیس‌های منتظر اجرا */
25
- export declare function setRunCount(count: number): void;
26
- /** تنظیم پرامیس‌های منتظر اجرا */
27
- export declare function setRunPromises(promises: PromiseMap): void;
28
16
  /** تنظیم کردن توکن */
29
17
  export declare function setToken(newToken: string): void;
30
18
  /** توکن را بر می‌گرداند */
@@ -57,4 +45,3 @@ export declare function getBackdrop(): HTMLDivElement;
57
45
  export declare function setOpenLinkFn(fn?: (link: string) => void): void;
58
46
  /** تابع مدیریت‌کننده‌ی لینک‌ها را برمی‌گرداند */
59
47
  export declare function getOpenLinkFn(): (link: string) => void;
60
- export {};
@@ -1,4 +1,3 @@
1
- import { InterOperation } from './interoperation';
2
1
  /**
3
2
  * ایونت آماده‌شدن توکن را بر می‌گرداند
4
3
  */
@@ -15,7 +14,3 @@ export declare function getCloseEvent(): Event;
15
14
  * ایونت آماده‌شدن حالت مهمان را بر می‌گرداند
16
15
  */
17
16
  export declare function setGuestReadyEvent(): Event;
18
- /**
19
- * ⁧eventهایی که از بیرون به داخل می‌ایند را اعتبار سنجی و سپس کار خواسته شده را انجام می‌دهد
20
- */
21
- export declare function handleEvents(interoperation: InterOperation): void;
@@ -1,34 +1,22 @@
1
- import { FunctionKeys } from 'utility-types';
2
- type MessageData<T = {}> = {
3
- /** شناسه داده */
4
- id: number;
5
- /** تابعی که داده برای آن ارسال شده است */
6
- action: string;
7
- /** داده موردنظر */
8
- data: T;
9
- };
10
- /**
11
- * این تابع برای فراخوانی متدهاییست که مقداری بر نمی‌گردانند
12
- */
13
- export declare function post(action: string, data?: object): void;
14
- /**
15
- * این تابع برای فراخوانی متدهاییست که مقدار بر می‌گردانند
16
- */
17
- export declare function run<A extends FunctionKeys<InterOperation>>(action: A, data?: object): Promise<ReturnType<InterOperation[A]>>;
18
1
  export declare class InterOperation {
2
+ private connection?;
19
3
  init(): Promise<void>;
4
+ private connectChild;
20
5
  /** توکن را از میزبان دریافت کرده و آن را ذخیره می‌کند. سپس به میزبان اعلام می‌کند که آماده‌ی ادامه‌ی کار است */
21
- setToken(data: MessageData<{
6
+ setToken(data: {
22
7
  token: string;
23
- }>): void;
8
+ }): void;
24
9
  /** بستن کتابخانه */
25
10
  close(): void;
26
11
  /** اطلاعات کتابخانه را به بیرون اطلاع می‌دهد */
27
- getConfig(data: MessageData): void;
12
+ getConfig(): {
13
+ color: import('../library-colors').Color;
14
+ theme: "light" | "dark" | undefined;
15
+ language: string;
16
+ };
28
17
  /** لینک موردنظر را به وسیله‌ی تابع از پیش تعریف‌شده باز می‌کند */
29
- openLink(data: MessageData<{
18
+ openLink(data: {
30
19
  link: string;
31
- }>): void;
20
+ }): void;
32
21
  setGuestReadyEvent(): void;
33
22
  }
34
- export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "samandesk",
3
- "version": "1.2.0",
3
+ "version": "2.0.0-beta1.0",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "files": [
@@ -11,19 +11,20 @@
11
11
  "types": "./dist/src/index.d.ts",
12
12
  "exports": {
13
13
  ".": {
14
+ "types": "./dist/src/index.d.ts",
14
15
  "import": "./dist/saman-desk.js",
15
- "require": "./dist/saman-desk.umd.cjs",
16
- "types": "./dist/src/index.d.ts"
16
+ "require": "./dist/saman-desk.umd.cjs"
17
17
  }
18
18
  },
19
19
  "scripts": {
20
20
  "start": "yarn link && cross-env VITE_DEV_MODE=1 yarn vite build --watch",
21
- "prepublish": "vite build"
21
+ "prepublish": "cross-env VITE_DEV_MODE=0 vite build"
22
22
  },
23
23
  "devDependencies": {
24
24
  "cross-env": "^7.0.3",
25
25
  "terser": "^5.39.0",
26
26
  "typescript": "^5.8.3",
27
+ "uncrypto": "^0.1.3",
27
28
  "utility-types": "^3.11.0",
28
29
  "vite": "^6.3.3",
29
30
  "vite-plugin-dts": "^4.5.3"