@arcanejs/toolkit 7.0.0 → 9.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/backend/components/base.d.mts +2 -1
- package/dist/backend/components/base.d.ts +2 -1
- package/dist/backend/components/base.js +2 -2
- package/dist/backend/components/base.mjs +1 -1
- package/dist/backend/components/button.d.mts +2 -1
- package/dist/backend/components/button.d.ts +2 -1
- package/dist/backend/components/button.js +3 -3
- package/dist/backend/components/button.mjs +2 -2
- package/dist/backend/components/group.d.mts +2 -1
- package/dist/backend/components/group.d.ts +2 -1
- package/dist/backend/components/group.js +3 -3
- package/dist/backend/components/group.mjs +2 -2
- package/dist/backend/components/label.d.mts +2 -1
- package/dist/backend/components/label.d.ts +2 -1
- package/dist/backend/components/label.js +3 -3
- package/dist/backend/components/label.mjs +2 -2
- package/dist/backend/components/rect.d.mts +2 -1
- package/dist/backend/components/rect.d.ts +2 -1
- package/dist/backend/components/rect.js +3 -3
- package/dist/backend/components/rect.mjs +2 -2
- package/dist/backend/components/slider-button.d.mts +2 -1
- package/dist/backend/components/slider-button.d.ts +2 -1
- package/dist/backend/components/slider-button.js +3 -3
- package/dist/backend/components/slider-button.mjs +2 -2
- package/dist/backend/components/switch.d.mts +2 -1
- package/dist/backend/components/switch.d.ts +2 -1
- package/dist/backend/components/switch.js +3 -3
- package/dist/backend/components/switch.mjs +2 -2
- package/dist/backend/components/tabs.d.mts +2 -1
- package/dist/backend/components/tabs.d.ts +2 -1
- package/dist/backend/components/tabs.js +3 -3
- package/dist/backend/components/tabs.mjs +2 -2
- package/dist/backend/components/text-input.d.mts +2 -1
- package/dist/backend/components/text-input.d.ts +2 -1
- package/dist/backend/components/text-input.js +3 -3
- package/dist/backend/components/text-input.mjs +2 -2
- package/dist/backend/components/timeline.d.mts +2 -1
- package/dist/backend/components/timeline.d.ts +2 -1
- package/dist/backend/components/timeline.js +3 -3
- package/dist/backend/components/timeline.mjs +2 -2
- package/dist/{chunk-IV3AE3CW.js → chunk-2R23ER4K.js} +3 -3
- package/dist/{chunk-R5OA7LLZ.mjs → chunk-5K7DK7CW.mjs} +1 -1
- package/dist/{chunk-RJLYYTZ6.mjs → chunk-7WTSYZOS.mjs} +1 -1
- package/dist/{chunk-2K4UT5QB.js → chunk-AYMITMVR.js} +3 -3
- package/dist/{chunk-K6V55JTG.mjs → chunk-KO24S32V.mjs} +1 -1
- package/dist/{chunk-XSKWLJOQ.js → chunk-KRGLXKY2.js} +4 -4
- package/dist/{chunk-JHWFQLLE.mjs → chunk-MNEFCU3M.mjs} +1 -1
- package/dist/{chunk-TF7N4O5G.js → chunk-NEFCI6N6.js} +2 -2
- package/dist/{chunk-TULW7CRV.mjs → chunk-NJW4ZG4X.mjs} +1 -1
- package/dist/{chunk-MHSAHTVN.mjs → chunk-QBZB56TQ.mjs} +1 -1
- package/dist/{chunk-UHEZQR2Q.js → chunk-QHCNKTKW.js} +2 -2
- package/dist/{chunk-4AGKM5NT.js → chunk-RELZ3VTJ.js} +3 -3
- package/dist/{chunk-7MQHRTBE.mjs → chunk-RGLKNCJ3.mjs} +1 -1
- package/dist/{chunk-A3RWE7HZ.js → chunk-SPYBETRJ.js} +3 -3
- package/dist/{chunk-GONHNB6V.mjs → chunk-UTTTCTUQ.mjs} +26 -5
- package/dist/{chunk-GXJ3JRRK.mjs → chunk-VD6S32ED.mjs} +1 -1
- package/dist/{chunk-5B65Q7RL.js → chunk-VTNAO4KC.js} +2 -2
- package/dist/{chunk-6PS3Q66F.mjs → chunk-Y3NPWW27.mjs} +1 -1
- package/dist/{chunk-CVY55KAR.js → chunk-Y5FC42KD.js} +3 -3
- package/dist/{chunk-WN3GXVUE.js → chunk-YNOJTE3G.js} +26 -5
- package/dist/frontend/entrypoint.js +43 -2
- package/dist/frontend/entrypoint.js.map +2 -2
- package/dist/frontend/index.js +69 -12
- package/dist/frontend/index.mjs +69 -12
- package/dist/index.d.mts +3 -2
- package/dist/index.d.ts +3 -2
- package/dist/index.js +183 -64
- package/dist/index.mjs +154 -35
- package/dist/{toolkit-Bglbv3ix.d.ts → toolkit-CKA9A4r-.d.ts} +116 -93
- package/dist/{toolkit-BPqxbDbk.d.mts → toolkit-GNytD78y.d.mts} +116 -93
- package/package.json +8 -8
package/dist/index.mjs
CHANGED
|
@@ -1,38 +1,38 @@
|
|
|
1
1
|
import {
|
|
2
2
|
Tab,
|
|
3
3
|
Tabs
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-5K7DK7CW.mjs";
|
|
5
5
|
import {
|
|
6
6
|
TextInput
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-VD6S32ED.mjs";
|
|
8
8
|
import {
|
|
9
9
|
Timeline
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-Y3NPWW27.mjs";
|
|
11
11
|
import {
|
|
12
12
|
IDMap
|
|
13
13
|
} from "./chunk-RGHJEMWG.mjs";
|
|
14
14
|
import {
|
|
15
15
|
Button
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-RGLKNCJ3.mjs";
|
|
17
17
|
import {
|
|
18
18
|
Group,
|
|
19
19
|
GroupHeader
|
|
20
|
-
} from "./chunk-
|
|
20
|
+
} from "./chunk-NJW4ZG4X.mjs";
|
|
21
21
|
import {
|
|
22
22
|
Label
|
|
23
|
-
} from "./chunk-
|
|
23
|
+
} from "./chunk-MNEFCU3M.mjs";
|
|
24
24
|
import {
|
|
25
25
|
Rect
|
|
26
|
-
} from "./chunk-
|
|
26
|
+
} from "./chunk-7WTSYZOS.mjs";
|
|
27
27
|
import {
|
|
28
28
|
SliderButton
|
|
29
|
-
} from "./chunk-
|
|
29
|
+
} from "./chunk-KO24S32V.mjs";
|
|
30
30
|
import {
|
|
31
31
|
Switch
|
|
32
|
-
} from "./chunk-
|
|
32
|
+
} from "./chunk-QBZB56TQ.mjs";
|
|
33
33
|
import {
|
|
34
34
|
EventEmitter
|
|
35
|
-
} from "./chunk-
|
|
35
|
+
} from "./chunk-UTTTCTUQ.mjs";
|
|
36
36
|
import {
|
|
37
37
|
__require
|
|
38
38
|
} from "./chunk-Y6FXYEAI.mjs";
|
|
@@ -69,12 +69,16 @@ var distDir = () => {
|
|
|
69
69
|
throw new Error(`Server running from unknown location: ${__dirname}`);
|
|
70
70
|
}
|
|
71
71
|
};
|
|
72
|
+
var UPLOAD_URL = /^\/upload\/([0-9a-f]+)$/;
|
|
73
|
+
var DOWNLOAD_URL = /^\/download\/([0-9a-f]+)$/;
|
|
72
74
|
var Server = class {
|
|
73
|
-
constructor(options, onNewConnection, onClosedConnection, onMessage, log) {
|
|
75
|
+
constructor(options, onNewConnection, onClosedConnection, onMessage, onUpload, onDownload, log) {
|
|
74
76
|
this.options = options;
|
|
75
77
|
this.onNewConnection = onNewConnection;
|
|
76
78
|
this.onClosedConnection = onClosedConnection;
|
|
77
79
|
this.onMessage = onMessage;
|
|
80
|
+
this.onUpload = onUpload;
|
|
81
|
+
this.onDownload = onDownload;
|
|
78
82
|
this.log = log;
|
|
79
83
|
this.title = options.title ?? "@arcanejs";
|
|
80
84
|
}
|
|
@@ -273,8 +277,45 @@ var Server = class {
|
|
|
273
277
|
}
|
|
274
278
|
}
|
|
275
279
|
}
|
|
276
|
-
|
|
277
|
-
|
|
280
|
+
const [uploadMatch, downloadMatch] = [
|
|
281
|
+
UPLOAD_URL.exec(pathname),
|
|
282
|
+
DOWNLOAD_URL.exec(pathname)
|
|
283
|
+
];
|
|
284
|
+
if (uploadMatch?.[1]) {
|
|
285
|
+
const id = uploadMatch[1];
|
|
286
|
+
this.log?.debug("Upload request for id: %s", id);
|
|
287
|
+
this.onUpload(id, req).then(() => {
|
|
288
|
+
res.writeHead(200, { "Content-Type": "text/plain" });
|
|
289
|
+
res.end("Upload successful", "utf-8");
|
|
290
|
+
}).catch((cause) => {
|
|
291
|
+
const error = new Error(`Error handling upload for id ${id}`, {
|
|
292
|
+
cause
|
|
293
|
+
});
|
|
294
|
+
this.log?.error(error);
|
|
295
|
+
res.writeHead(500, { "Content-Type": "text/plain" });
|
|
296
|
+
res.end("Error handling upload", "utf-8");
|
|
297
|
+
});
|
|
298
|
+
} else if (downloadMatch?.[1]) {
|
|
299
|
+
const id = downloadMatch[1];
|
|
300
|
+
this.log?.debug("Download request for id: %s", id);
|
|
301
|
+
this.onDownload(id).then((handler) => handler()).then(({ stream, headers }) => {
|
|
302
|
+
res.writeHead(200, {
|
|
303
|
+
"Content-Type": "application/octet-stream",
|
|
304
|
+
...headers
|
|
305
|
+
});
|
|
306
|
+
stream.pipe(res);
|
|
307
|
+
}).catch((cause) => {
|
|
308
|
+
const error = new Error(`Error handling download for id ${id}`, {
|
|
309
|
+
cause
|
|
310
|
+
});
|
|
311
|
+
this.log?.error(error);
|
|
312
|
+
res.writeHead(500, { "Content-Type": "text/plain" });
|
|
313
|
+
res.end("Error handling download", "utf-8");
|
|
314
|
+
});
|
|
315
|
+
} else {
|
|
316
|
+
res.writeHead(404, { "Content-Type": "text/plain" });
|
|
317
|
+
res.end("not found", "utf-8");
|
|
318
|
+
}
|
|
278
319
|
};
|
|
279
320
|
parsePathname = (url) => {
|
|
280
321
|
if (!url) return "";
|
|
@@ -327,6 +368,7 @@ var Server = class {
|
|
|
327
368
|
import { WebSocketServer } from "ws";
|
|
328
369
|
import { createServer } from "http";
|
|
329
370
|
import { v4 as uuidv4 } from "uuid";
|
|
371
|
+
import { randomBytes } from "node:crypto";
|
|
330
372
|
var normalizeClockSyncOptions = (clockSync) => {
|
|
331
373
|
if (!clockSync) {
|
|
332
374
|
return null;
|
|
@@ -353,6 +395,8 @@ var Toolkit = class {
|
|
|
353
395
|
/** @hidden */
|
|
354
396
|
events = new EventEmitter();
|
|
355
397
|
server;
|
|
398
|
+
uploads = /* @__PURE__ */ new Map();
|
|
399
|
+
downloads = /* @__PURE__ */ new Map();
|
|
356
400
|
constructor(options = {}) {
|
|
357
401
|
this.options = {
|
|
358
402
|
...DEFAULT_LIGHT_DESK_OPTIONS,
|
|
@@ -369,6 +413,8 @@ var Toolkit = class {
|
|
|
369
413
|
this.onNewConnection,
|
|
370
414
|
this.onClosedConnection,
|
|
371
415
|
this.onMessage,
|
|
416
|
+
this.onUpload,
|
|
417
|
+
this.onDownload,
|
|
372
418
|
this.options.log
|
|
373
419
|
);
|
|
374
420
|
}
|
|
@@ -502,6 +548,25 @@ var Toolkit = class {
|
|
|
502
548
|
const con = this.connections.get(connection);
|
|
503
549
|
this.connections.delete(connection);
|
|
504
550
|
if (con) {
|
|
551
|
+
let inProgressUploads = 0;
|
|
552
|
+
let inProgressDownloads = 0;
|
|
553
|
+
for (const [id, upload] of this.uploads.entries()) {
|
|
554
|
+
if (upload.connection === connection) {
|
|
555
|
+
this.uploads.delete(id);
|
|
556
|
+
inProgressUploads++;
|
|
557
|
+
}
|
|
558
|
+
}
|
|
559
|
+
for (const [id, download] of this.downloads.entries()) {
|
|
560
|
+
if (download.connection === connection) {
|
|
561
|
+
this.downloads.delete(id);
|
|
562
|
+
inProgressDownloads++;
|
|
563
|
+
}
|
|
564
|
+
}
|
|
565
|
+
if (inProgressUploads > 0 || inProgressDownloads > 0) {
|
|
566
|
+
this.log()?.info(
|
|
567
|
+
`Connection closed with ${inProgressUploads} in-progress uploads and ${inProgressDownloads} in-progress downloads`
|
|
568
|
+
);
|
|
569
|
+
}
|
|
505
570
|
this.events.emit("closed-connection", con.publicConnection);
|
|
506
571
|
}
|
|
507
572
|
};
|
|
@@ -509,12 +574,32 @@ var Toolkit = class {
|
|
|
509
574
|
try {
|
|
510
575
|
const rg = this.rootGroup;
|
|
511
576
|
if (rg) {
|
|
512
|
-
const
|
|
577
|
+
const handlerValue = await new Promise(
|
|
513
578
|
(resolve2, reject) => rg.routeCall(this.componentIDMap, call, publicConnection, {
|
|
514
579
|
resolve: resolve2,
|
|
515
580
|
reject
|
|
516
581
|
})
|
|
517
582
|
);
|
|
583
|
+
let returnValue;
|
|
584
|
+
if (call.type === "component-call") {
|
|
585
|
+
returnValue = handlerValue;
|
|
586
|
+
} else if (call.type === "component-call-upload") {
|
|
587
|
+
const uploadHandler = handlerValue;
|
|
588
|
+
const secureId = randomBytes(32).toString("hex");
|
|
589
|
+
this.uploads.set(secureId, {
|
|
590
|
+
connection,
|
|
591
|
+
handler: uploadHandler
|
|
592
|
+
});
|
|
593
|
+
returnValue = secureId;
|
|
594
|
+
} else if (call.type === "component-call-download") {
|
|
595
|
+
const downloadHandler = handlerValue;
|
|
596
|
+
const secureId = randomBytes(32).toString("hex");
|
|
597
|
+
this.downloads.set(secureId, {
|
|
598
|
+
connection,
|
|
599
|
+
handler: downloadHandler
|
|
600
|
+
});
|
|
601
|
+
returnValue = secureId;
|
|
602
|
+
}
|
|
518
603
|
connection.sendMessage({
|
|
519
604
|
type: "call-response",
|
|
520
605
|
namespace: call.namespace,
|
|
@@ -525,13 +610,15 @@ var Toolkit = class {
|
|
|
525
610
|
} else {
|
|
526
611
|
throw new Error("No root group set");
|
|
527
612
|
}
|
|
528
|
-
} catch (
|
|
613
|
+
} catch (cause) {
|
|
614
|
+
const error = new Error(`Error handling call`, { cause });
|
|
615
|
+
this.log()?.error(error);
|
|
529
616
|
connection.sendMessage({
|
|
530
617
|
type: "call-response",
|
|
531
618
|
namespace: call.namespace,
|
|
532
619
|
requestId: call.requestId,
|
|
533
620
|
success: false,
|
|
534
|
-
errorMessage: `${
|
|
621
|
+
errorMessage: `${cause}`
|
|
535
622
|
});
|
|
536
623
|
}
|
|
537
624
|
};
|
|
@@ -547,25 +634,57 @@ var Toolkit = class {
|
|
|
547
634
|
message,
|
|
548
635
|
publicConnection.uuid
|
|
549
636
|
);
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
this.rootGroup
|
|
554
|
-
this.
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
637
|
+
try {
|
|
638
|
+
switch (message.type) {
|
|
639
|
+
case "component-message":
|
|
640
|
+
if (this.rootGroup)
|
|
641
|
+
this.rootGroup.routeMessage(
|
|
642
|
+
this.componentIDMap,
|
|
643
|
+
message,
|
|
644
|
+
publicConnection
|
|
645
|
+
);
|
|
646
|
+
break;
|
|
647
|
+
case "component-call":
|
|
648
|
+
case "component-call-upload":
|
|
649
|
+
case "component-call-download":
|
|
650
|
+
this.handleCall(connection, publicConnection, message);
|
|
651
|
+
break;
|
|
652
|
+
case "ping": {
|
|
653
|
+
connection.sendMessage({
|
|
654
|
+
type: "pong",
|
|
655
|
+
pingId: message.pingId,
|
|
656
|
+
serverTimeMillis: Date.now()
|
|
657
|
+
});
|
|
658
|
+
break;
|
|
659
|
+
}
|
|
660
|
+
}
|
|
661
|
+
} catch (cause) {
|
|
662
|
+
const error = new Error(
|
|
663
|
+
`Error handling message: ${JSON.stringify(message)}`,
|
|
664
|
+
{ cause }
|
|
665
|
+
);
|
|
666
|
+
this.log()?.error(error);
|
|
667
|
+
}
|
|
668
|
+
};
|
|
669
|
+
onUpload = async (id, data) => {
|
|
670
|
+
const upload = this.uploads.get(id);
|
|
671
|
+
if (!upload) {
|
|
672
|
+
throw new Error(`No upload handler found for id: ${id}`);
|
|
673
|
+
}
|
|
674
|
+
await upload.handler(data);
|
|
675
|
+
this.uploads.delete(id);
|
|
676
|
+
};
|
|
677
|
+
onDownload = async (id) => {
|
|
678
|
+
const download = this.downloads.get(id);
|
|
679
|
+
if (!download) {
|
|
680
|
+
throw new Error(`No download handler found for id: ${id}`);
|
|
681
|
+
}
|
|
682
|
+
return download.handler;
|
|
683
|
+
};
|
|
684
|
+
sendNotification = (notification, filter) => {
|
|
685
|
+
for (const [connection, meta] of this.connections.entries()) {
|
|
686
|
+
if (!filter || filter(meta.publicConnection)) {
|
|
687
|
+
connection.sendMessage(notification);
|
|
569
688
|
}
|
|
570
689
|
}
|
|
571
690
|
};
|
|
@@ -4,10 +4,115 @@ import _ from 'lodash';
|
|
|
4
4
|
import * as http from 'http';
|
|
5
5
|
import { Application } from 'express';
|
|
6
6
|
import { WebSocket } from 'ws';
|
|
7
|
-
import {
|
|
7
|
+
import { BaseComponentProto, AnyClientComponentMessage, AnyClientComponentCall, AnyClientComponentCallUpload, AnyClientComponentCallDownload, ReturnForPair, ClientMessage, ServerMessage, BaseNotificationMessage } from '@arcanejs/protocol';
|
|
8
|
+
import { Readable } from 'node:stream';
|
|
9
|
+
import { I as IDMap } from './id-map-DxQ3_gyA.js';
|
|
8
10
|
import * as proto from '@arcanejs/protocol/core';
|
|
9
11
|
import { GroupComponentStyle } from '@arcanejs/protocol/styles';
|
|
10
|
-
|
|
12
|
+
|
|
13
|
+
type CallUploadResponse = (data: Readable) => Promise<void>;
|
|
14
|
+
type CallDownloadResponse = () => Promise<{
|
|
15
|
+
stream: Readable;
|
|
16
|
+
headers: Record<string, string>;
|
|
17
|
+
}>;
|
|
18
|
+
declare abstract class Base<Namespace extends string, Proto extends BaseComponentProto<Namespace, string>, Props, CallPairs = any, CallActions extends string & keyof CallPairs = any> {
|
|
19
|
+
/** @hidden */
|
|
20
|
+
private parent;
|
|
21
|
+
/** @hidden */
|
|
22
|
+
private readonly defaultProps;
|
|
23
|
+
/** @hidden */
|
|
24
|
+
private _props;
|
|
25
|
+
/** @hidden */
|
|
26
|
+
private _onPropsUpdated;
|
|
27
|
+
constructor(defaultProps: Props, props?: Partial<Props>, options?: {
|
|
28
|
+
onPropsUpdated?: (oldProps: Props) => void;
|
|
29
|
+
});
|
|
30
|
+
/**
|
|
31
|
+
* Call if
|
|
32
|
+
*/
|
|
33
|
+
triggerInitialPropsUpdate: () => void;
|
|
34
|
+
log: () => Logger | null;
|
|
35
|
+
get props(): Props;
|
|
36
|
+
set props(props: Partial<Props>);
|
|
37
|
+
setProps: (props: Partial<Props>) => void;
|
|
38
|
+
updateProps: (updates: Partial<Props>) => void;
|
|
39
|
+
/** @hidden */
|
|
40
|
+
setParent(parent: Parent | null): void;
|
|
41
|
+
/** @hidden */
|
|
42
|
+
updateTree(): void;
|
|
43
|
+
/** @hidden */
|
|
44
|
+
abstract getProtoInfo(idMap: IDMap, context: ToolkitRenderContext): Proto;
|
|
45
|
+
/** @hidden */
|
|
46
|
+
handleMessage(_message: AnyClientComponentMessage, _connection: ToolkitConnection): void;
|
|
47
|
+
/** @hidden */
|
|
48
|
+
handleAnyCall(message: AnyClientComponentCall | AnyClientComponentCallUpload | AnyClientComponentCallDownload, _connection: ToolkitConnection): Promise<ReturnForPair<CallPairs, CallActions> | CallUploadResponse | CallDownloadResponse>;
|
|
49
|
+
/** @hidden */
|
|
50
|
+
handleCall(_call: AnyClientComponentCall, _connection: ToolkitConnection): Promise<ReturnForPair<CallPairs, CallActions>>;
|
|
51
|
+
/** @hidden */
|
|
52
|
+
handleCallUpload(_call: AnyClientComponentCallUpload, _connection: ToolkitConnection): Promise<CallUploadResponse>;
|
|
53
|
+
/** @hidden */
|
|
54
|
+
handleCallDownload(_call: AnyClientComponentCallDownload, _connection: ToolkitConnection): Promise<CallDownloadResponse>;
|
|
55
|
+
routeMessage(_idMap: IDMap, _message: AnyClientComponentMessage, _connection: ToolkitConnection): void;
|
|
56
|
+
routeCall(_idMap: IDMap, _call: AnyClientComponentCall | AnyClientComponentCallUpload | AnyClientComponentCallDownload, _connection: ToolkitConnection, _callbacks: {
|
|
57
|
+
resolve: (result: unknown) => void;
|
|
58
|
+
reject: (error: unknown) => void;
|
|
59
|
+
}): void;
|
|
60
|
+
}
|
|
61
|
+
type AnyComponent = Base<string, BaseComponentProto<string, string>, any>;
|
|
62
|
+
/** @hidden */
|
|
63
|
+
interface Parent {
|
|
64
|
+
updateTree(): void;
|
|
65
|
+
removeChild(component: AnyComponent): void;
|
|
66
|
+
log(): Logger | null;
|
|
67
|
+
}
|
|
68
|
+
declare abstract class BaseParent<Namespace extends string, Proto extends BaseComponentProto<Namespace, string>, T, CallPairs = any, CallActions extends string & keyof CallPairs = any> extends Base<Namespace, Proto, T, CallPairs, CallActions> implements Parent {
|
|
69
|
+
/** @hidden */
|
|
70
|
+
private children;
|
|
71
|
+
abstract validateChildren(children: AnyComponent[]): void;
|
|
72
|
+
appendChildren: <CS extends AnyComponent[]>(...children: CS) => CS;
|
|
73
|
+
appendChild: <C extends AnyComponent>(child: C) => C;
|
|
74
|
+
removeChild: (component: AnyComponent) => void;
|
|
75
|
+
removeAllChildren: () => void;
|
|
76
|
+
/**
|
|
77
|
+
* Return all children components that messages need to be routed to
|
|
78
|
+
*/
|
|
79
|
+
getChildren: () => readonly AnyComponent[];
|
|
80
|
+
/**
|
|
81
|
+
* TODO: we can do this better, right now it broadcasts the message to all
|
|
82
|
+
* components of the tree
|
|
83
|
+
*
|
|
84
|
+
* @hidden
|
|
85
|
+
*/
|
|
86
|
+
routeMessage(idMap: IDMap, message: AnyClientComponentMessage, connection: ToolkitConnection): void;
|
|
87
|
+
routeCall(idMap: IDMap, call: AnyClientComponentCall | AnyClientComponentCallUpload | AnyClientComponentCallDownload, connection: ToolkitConnection, callbacks: {
|
|
88
|
+
resolve: (result: unknown) => void;
|
|
89
|
+
reject: (error: unknown) => void;
|
|
90
|
+
}): Promise<void>;
|
|
91
|
+
insertBefore(child: AnyComponent, beforeChild: AnyComponent): void;
|
|
92
|
+
}
|
|
93
|
+
interface Listenable<Map extends Record<string, (...args: any[]) => void>> {
|
|
94
|
+
addListener<T extends keyof Map>(type: T, listener: Map[T]): void;
|
|
95
|
+
removeListener<T extends keyof Map>(type: T, listener: Map[T]): void;
|
|
96
|
+
}
|
|
97
|
+
declare class EventEmitter<Map extends Record<string, (...args: any[]) => void>> implements Listenable<Map> {
|
|
98
|
+
private readonly listeners;
|
|
99
|
+
addListener: <T extends keyof Map>(type: T, listener: Map[T]) => void;
|
|
100
|
+
removeListener: <T extends keyof Map>(type: T, listener: Map[T]) => void;
|
|
101
|
+
emit: <T extends keyof Map>(type: T, ...args: Parameters<Map[T]>) => Promise<ReturnType<Map[T]>[]>;
|
|
102
|
+
/**
|
|
103
|
+
* Like {@link emit},
|
|
104
|
+
* but ensures only a single listener exists and returns its result.
|
|
105
|
+
*/
|
|
106
|
+
call: <T extends keyof Map>(type: T, ...args: Parameters<Map[T]>) => Promise<ReturnType<Map[T]>>;
|
|
107
|
+
/**
|
|
108
|
+
* Process prop changes to update listeners
|
|
109
|
+
*/
|
|
110
|
+
processPropChanges: <Mapping extends Record<string, keyof Map>, Props extends { [key in keyof Mapping]?: Map[Mapping[key]] | null | undefined; }>(
|
|
111
|
+
/**
|
|
112
|
+
* Mapping from prop key to event name
|
|
113
|
+
*/
|
|
114
|
+
mapping: Mapping, oldProps: Props, newProps: Props) => void;
|
|
115
|
+
}
|
|
11
116
|
|
|
12
117
|
interface Connection {
|
|
13
118
|
sendMessage(msg: ServerMessage): void;
|
|
@@ -17,12 +122,14 @@ declare class Server<TAdditionalFiles extends ToolkitAdditionalFiles = Record<ne
|
|
|
17
122
|
private readonly onNewConnection;
|
|
18
123
|
private readonly onClosedConnection;
|
|
19
124
|
private readonly onMessage;
|
|
125
|
+
private readonly onUpload;
|
|
126
|
+
private readonly onDownload;
|
|
20
127
|
private readonly log?;
|
|
21
128
|
private staticFiles;
|
|
22
129
|
private htmlContext;
|
|
23
130
|
private staticFilesInitPromise;
|
|
24
131
|
private readonly title;
|
|
25
|
-
constructor(options: ToolkitOptions<TAdditionalFiles>, onNewConnection: (connection: Connection) => void, onClosedConnection: (connection: Connection) => void, onMessage: (connection: Connection, message: ClientMessage) => void, log?: Logger | undefined);
|
|
132
|
+
constructor(options: ToolkitOptions<TAdditionalFiles>, onNewConnection: (connection: Connection) => void, onClosedConnection: (connection: Connection) => void, onMessage: (connection: Connection, message: ClientMessage) => void, onUpload: (id: string, data: Readable) => Promise<void>, onDownload: (id: string) => Promise<CallDownloadResponse>, log?: Logger | undefined);
|
|
26
133
|
private getEntrypointPaths;
|
|
27
134
|
private fileExists;
|
|
28
135
|
private ensureStaticFilesInitialized;
|
|
@@ -147,95 +254,6 @@ type InitializationOptions<TAdditionalFiles extends ToolkitAdditionalFiles = Rec
|
|
|
147
254
|
setup: (server: Server<TAdditionalFiles>) => void;
|
|
148
255
|
};
|
|
149
256
|
|
|
150
|
-
declare abstract class Base<Namespace extends string, Proto extends BaseComponentProto<Namespace, string>, Props, CallPairs = any, CallActions extends string & keyof CallPairs = any> {
|
|
151
|
-
/** @hidden */
|
|
152
|
-
private parent;
|
|
153
|
-
/** @hidden */
|
|
154
|
-
private readonly defaultProps;
|
|
155
|
-
/** @hidden */
|
|
156
|
-
private _props;
|
|
157
|
-
/** @hidden */
|
|
158
|
-
private _onPropsUpdated;
|
|
159
|
-
constructor(defaultProps: Props, props?: Partial<Props>, options?: {
|
|
160
|
-
onPropsUpdated?: (oldProps: Props) => void;
|
|
161
|
-
});
|
|
162
|
-
/**
|
|
163
|
-
* Call if
|
|
164
|
-
*/
|
|
165
|
-
triggerInitialPropsUpdate: () => void;
|
|
166
|
-
log: () => Logger | null;
|
|
167
|
-
get props(): Props;
|
|
168
|
-
set props(props: Partial<Props>);
|
|
169
|
-
setProps: (props: Partial<Props>) => void;
|
|
170
|
-
updateProps: (updates: Partial<Props>) => void;
|
|
171
|
-
/** @hidden */
|
|
172
|
-
setParent(parent: Parent | null): void;
|
|
173
|
-
/** @hidden */
|
|
174
|
-
updateTree(): void;
|
|
175
|
-
/** @hidden */
|
|
176
|
-
abstract getProtoInfo(idMap: IDMap, context: ToolkitRenderContext): Proto;
|
|
177
|
-
/** @hidden */
|
|
178
|
-
handleMessage(_message: AnyClientComponentMessage, _connection: ToolkitConnection): void;
|
|
179
|
-
/** @hidden */
|
|
180
|
-
handleCall(_call: AnyClientComponentCall, _connection: ToolkitConnection): Promise<ReturnForPair<CallPairs, CallActions>>;
|
|
181
|
-
routeMessage(_idMap: IDMap, _message: AnyClientComponentMessage, _connection: ToolkitConnection): void;
|
|
182
|
-
routeCall(_idMap: IDMap, _call: AnyClientComponentCall, _connection: ToolkitConnection, _callbacks: {
|
|
183
|
-
resolve: (result: unknown) => void;
|
|
184
|
-
reject: (error: unknown) => void;
|
|
185
|
-
}): void;
|
|
186
|
-
}
|
|
187
|
-
type AnyComponent = Base<string, BaseComponentProto<string, string>, any>;
|
|
188
|
-
/** @hidden */
|
|
189
|
-
interface Parent {
|
|
190
|
-
updateTree(): void;
|
|
191
|
-
removeChild(component: AnyComponent): void;
|
|
192
|
-
log(): Logger | null;
|
|
193
|
-
}
|
|
194
|
-
declare abstract class BaseParent<Namespace extends string, Proto extends BaseComponentProto<Namespace, string>, T, CallPairs = any, CallActions extends string & keyof CallPairs = any> extends Base<Namespace, Proto, T, CallPairs, CallActions> implements Parent {
|
|
195
|
-
/** @hidden */
|
|
196
|
-
private children;
|
|
197
|
-
abstract validateChildren(children: AnyComponent[]): void;
|
|
198
|
-
appendChildren: <CS extends AnyComponent[]>(...children: CS) => CS;
|
|
199
|
-
appendChild: <C extends AnyComponent>(child: C) => C;
|
|
200
|
-
removeChild: (component: AnyComponent) => void;
|
|
201
|
-
removeAllChildren: () => void;
|
|
202
|
-
/**
|
|
203
|
-
* Return all children components that messages need to be routed to
|
|
204
|
-
*/
|
|
205
|
-
getChildren: () => readonly AnyComponent[];
|
|
206
|
-
/**
|
|
207
|
-
* TODO: we can do this better, right now it broadcasts the message to all
|
|
208
|
-
* components of the tree
|
|
209
|
-
*
|
|
210
|
-
* @hidden
|
|
211
|
-
*/
|
|
212
|
-
routeMessage(idMap: IDMap, message: AnyClientComponentMessage, connection: ToolkitConnection): void;
|
|
213
|
-
routeCall(idMap: IDMap, call: AnyClientComponentCall, connection: ToolkitConnection, callbacks: {
|
|
214
|
-
resolve: (result: unknown) => void;
|
|
215
|
-
reject: (error: unknown) => void;
|
|
216
|
-
}): Promise<void>;
|
|
217
|
-
insertBefore(child: AnyComponent, beforeChild: AnyComponent): void;
|
|
218
|
-
}
|
|
219
|
-
interface Listenable<Map extends Record<string, (...args: any[]) => void>> {
|
|
220
|
-
addListener<T extends keyof Map>(type: T, listener: Map[T]): void;
|
|
221
|
-
removeListener<T extends keyof Map>(type: T, listener: Map[T]): void;
|
|
222
|
-
}
|
|
223
|
-
declare class EventEmitter<Map extends Record<string, (...args: any[]) => void>> implements Listenable<Map> {
|
|
224
|
-
private readonly listeners;
|
|
225
|
-
addListener: <T extends keyof Map>(type: T, listener: Map[T]) => void;
|
|
226
|
-
removeListener: <T extends keyof Map>(type: T, listener: Map[T]) => void;
|
|
227
|
-
emit: <T extends keyof Map>(type: T, ...args: Parameters<Map[T]>) => Promise<ReturnType<Map[T]>[]>;
|
|
228
|
-
/**
|
|
229
|
-
* Like {@link emit},
|
|
230
|
-
* but ensures only a single listener exists and returns its result.
|
|
231
|
-
*/
|
|
232
|
-
call: <T extends keyof Map>(type: T, ...args: Parameters<Map[T]>) => Promise<ReturnType<Map[T]>>;
|
|
233
|
-
/**
|
|
234
|
-
* Process prop changes to update listeners
|
|
235
|
-
*/
|
|
236
|
-
processPropChanges: <Mapping extends Record<string, keyof Map>, Props extends { [key in keyof Mapping]?: Map[Mapping[key]] | null | undefined; }>(mapping: Mapping, oldProps: Props, newProps: Props) => void;
|
|
237
|
-
}
|
|
238
|
-
|
|
239
257
|
type Events$2 = {
|
|
240
258
|
click: (connection: ToolkitConnection) => void | Promise<void>;
|
|
241
259
|
};
|
|
@@ -338,6 +356,8 @@ declare class Toolkit<TAdditionalFiles extends ToolkitAdditionalFiles = Record<n
|
|
|
338
356
|
/** @hidden */
|
|
339
357
|
private readonly events;
|
|
340
358
|
private readonly server;
|
|
359
|
+
private readonly uploads;
|
|
360
|
+
private readonly downloads;
|
|
341
361
|
constructor(options?: Partial<ToolkitOptions<TAdditionalFiles>>);
|
|
342
362
|
addListener: <T extends keyof Events>(type: T, listener: Events[T]) => void;
|
|
343
363
|
removeListener: <T extends keyof Events>(type: T, listener: Events[T]) => void;
|
|
@@ -352,6 +372,9 @@ declare class Toolkit<TAdditionalFiles extends ToolkitAdditionalFiles = Record<n
|
|
|
352
372
|
private onClosedConnection;
|
|
353
373
|
private handleCall;
|
|
354
374
|
private onMessage;
|
|
375
|
+
private onUpload;
|
|
376
|
+
private onDownload;
|
|
377
|
+
sendNotification: (notification: BaseNotificationMessage<string, string>, filter?: (connection: ToolkitConnection) => boolean) => void;
|
|
355
378
|
}
|
|
356
379
|
|
|
357
|
-
export { type AnyComponent as A, Button as B, EventEmitter as E, Group as G, type InternalProps$1 as I, type Listenable as L, type Parent as P, Toolkit as T, type ToolkitConnection as a, type ToolkitRenderContext as b, type ToolkitServerListenerOptions as c, type ToolkitServerListener as d, type ToolkitAdditionalFiles as e, type ToolkitClockSyncOptions as f, type ToolkitCoreAssetRelativePath as g, type ToolkitHtmlPageContext as h, type ToolkitOptions as i, type ToolkitStaticFile as j, type ToolkitStaticFileResolver as k, GroupHeader as l, Base as m, BaseParent as n, type Events$2 as
|
|
380
|
+
export { type AnyComponent as A, Button as B, type CallUploadResponse as C, EventEmitter as E, Group as G, type InternalProps$1 as I, type Listenable as L, type Parent as P, Toolkit as T, type ToolkitConnection as a, type ToolkitRenderContext as b, type ToolkitServerListenerOptions as c, type ToolkitServerListener as d, type ToolkitAdditionalFiles as e, type ToolkitClockSyncOptions as f, type ToolkitCoreAssetRelativePath as g, type ToolkitHtmlPageContext as h, type ToolkitOptions as i, type ToolkitStaticFile as j, type ToolkitStaticFileResolver as k, GroupHeader as l, Base as m, BaseParent as n, type CallDownloadResponse as o, type Events$2 as p, type ButtonMode as q, type Props$1 as r, type Events$1 as s, type InternalProps as t, type Props as u };
|