samandesk 1.1.0 → 1.1.2

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