@fraqjs/fraq 0.10.2 → 0.11.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/index.d.mts +38 -18
- package/dist/index.mjs +122 -80
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -405,7 +405,7 @@ declare namespace types_d_exports {
|
|
|
405
405
|
};
|
|
406
406
|
}
|
|
407
407
|
declare const milkyVersion = '1.3';
|
|
408
|
-
declare const milkyPackageVersion = '1.3.0-rc.
|
|
408
|
+
declare const milkyPackageVersion = '1.3.0-rc.2';
|
|
409
409
|
/** 机器人离线事件 */
|
|
410
410
|
interface BotOfflineEvent {
|
|
411
411
|
/** 数据类型区分字段,表示自身为机器人离线事件 */
|
|
@@ -2846,7 +2846,7 @@ interface GetImplInfoOutput {
|
|
|
2846
2846
|
| 'iphone'
|
|
2847
2847
|
| 'harmony'
|
|
2848
2848
|
| 'watch';
|
|
2849
|
-
/** 协议端实现的 Milky 协议版本,目前为 "1.
|
|
2849
|
+
/** 协议端实现的 Milky 协议版本,目前为 "1.3" */
|
|
2850
2850
|
milky_version: string;
|
|
2851
2851
|
}
|
|
2852
2852
|
/** 获取协议端信息 API 响应数据 */
|
|
@@ -2868,7 +2868,7 @@ interface GetImplInfoOutput_ZodInput {
|
|
|
2868
2868
|
| 'iphone'
|
|
2869
2869
|
| 'harmony'
|
|
2870
2870
|
| 'watch';
|
|
2871
|
-
/** 协议端实现的 Milky 协议版本,目前为 "1.
|
|
2871
|
+
/** 协议端实现的 Milky 协议版本,目前为 "1.3" */
|
|
2872
2872
|
milky_version: string;
|
|
2873
2873
|
}
|
|
2874
2874
|
/** 获取用户个人信息 API 请求参数 */
|
|
@@ -4151,6 +4151,8 @@ interface GetPrivateFileDownloadUrlInput {
|
|
|
4151
4151
|
file_id: string;
|
|
4152
4152
|
/** 文件的 TriSHA1 哈希值 */
|
|
4153
4153
|
file_hash: string;
|
|
4154
|
+
/** 是否为自己发送的文件 */
|
|
4155
|
+
is_self_send: boolean;
|
|
4154
4156
|
}
|
|
4155
4157
|
/** 获取私聊文件下载链接 API 请求参数 */
|
|
4156
4158
|
interface GetPrivateFileDownloadUrlInput_ZodInput {
|
|
@@ -4160,6 +4162,8 @@ interface GetPrivateFileDownloadUrlInput_ZodInput {
|
|
|
4160
4162
|
file_id: string;
|
|
4161
4163
|
/** 文件的 TriSHA1 哈希值 */
|
|
4162
4164
|
file_hash: string;
|
|
4165
|
+
/** 是否为自己发送的文件 */
|
|
4166
|
+
is_self_send?: boolean | null | undefined;
|
|
4163
4167
|
}
|
|
4164
4168
|
/** 获取私聊文件下载链接 API 响应数据 */
|
|
4165
4169
|
interface GetPrivateFileDownloadUrlOutput {
|
|
@@ -5396,13 +5400,7 @@ type EventMap = {
|
|
|
5396
5400
|
};
|
|
5397
5401
|
//#endregion
|
|
5398
5402
|
//#region src/protocol/client.d.ts
|
|
5399
|
-
interface
|
|
5400
|
-
closed: Promise<void>;
|
|
5401
|
-
stop(): void | Promise<void>;
|
|
5402
|
-
}
|
|
5403
|
-
interface MilkyClient extends ApiEndpoints {
|
|
5404
|
-
startEvents(onEvent: (event: Event) => void | Promise<void>): Promise<MilkyEventSubscription>;
|
|
5405
|
-
}
|
|
5403
|
+
interface MilkyClient extends ApiEndpoints {}
|
|
5406
5404
|
declare class MilkyClientBase {
|
|
5407
5405
|
readonly baseUrl: string;
|
|
5408
5406
|
readonly wsBaseUrl: string;
|
|
@@ -5415,10 +5413,26 @@ declare class MilkyClientBase {
|
|
|
5415
5413
|
},
|
|
5416
5414
|
);
|
|
5417
5415
|
callApi(endpoint: string, params?: unknown): Promise<unknown>;
|
|
5418
|
-
startEvents(onEvent: (event: Event) => void | Promise<void>): Promise<MilkyEventSubscription>;
|
|
5419
5416
|
}
|
|
5420
5417
|
declare function createMilkyClient(...params: ConstructorParameters<typeof MilkyClientBase>): MilkyClient;
|
|
5421
5418
|
//#endregion
|
|
5419
|
+
//#region src/protocol/event.d.ts
|
|
5420
|
+
interface MilkyEventSubscription {
|
|
5421
|
+
closed: Promise<void>;
|
|
5422
|
+
stop(): void | Promise<void>;
|
|
5423
|
+
}
|
|
5424
|
+
interface MilkyEventSource {
|
|
5425
|
+
readonly name?: string;
|
|
5426
|
+
start(onEvent: (event: Event) => void | Promise<void>): Promise<MilkyEventSubscription>;
|
|
5427
|
+
}
|
|
5428
|
+
interface MilkyWebSocketEventSourceOptions {
|
|
5429
|
+
accessToken?: string;
|
|
5430
|
+
}
|
|
5431
|
+
declare function createMilkyWebSocketEventSource(
|
|
5432
|
+
baseUrl: string | URL,
|
|
5433
|
+
options?: MilkyWebSocketEventSourceOptions,
|
|
5434
|
+
): MilkyEventSource;
|
|
5435
|
+
//#endregion
|
|
5422
5436
|
//#region src/routing/tokenizer.d.ts
|
|
5423
5437
|
type Token =
|
|
5424
5438
|
| string
|
|
@@ -5486,6 +5500,8 @@ declare class Parameter<T> {
|
|
|
5486
5500
|
description?: string;
|
|
5487
5501
|
constructor(capturer: Capturer<T>);
|
|
5488
5502
|
describe(description: string): this;
|
|
5503
|
+
refine<U extends T>(predicate: (value: T) => value is U): Parameter<U>;
|
|
5504
|
+
refine(predicate: (value: T) => boolean): Parameter<T>;
|
|
5489
5505
|
}
|
|
5490
5506
|
declare namespace param {
|
|
5491
5507
|
function literal<T extends string>(literal: T): Parameter<T>;
|
|
@@ -5527,6 +5543,7 @@ interface SessionReplyOptions {
|
|
|
5527
5543
|
withMention?: boolean;
|
|
5528
5544
|
}
|
|
5529
5545
|
interface Session {
|
|
5546
|
+
selfId: number;
|
|
5530
5547
|
raw: IncomingMessage;
|
|
5531
5548
|
reply(
|
|
5532
5549
|
textOrSegments: string | OutgoingSegment_ZodInput[],
|
|
@@ -5717,6 +5734,7 @@ interface ContextOptions {
|
|
|
5717
5734
|
}
|
|
5718
5735
|
interface ContextUrlOptions {
|
|
5719
5736
|
accessToken?: string;
|
|
5737
|
+
installEventSource?: boolean;
|
|
5720
5738
|
}
|
|
5721
5739
|
declare class Context {
|
|
5722
5740
|
readonly client: MilkyClient;
|
|
@@ -5729,6 +5747,7 @@ declare class Context {
|
|
|
5729
5747
|
private readonly plugins;
|
|
5730
5748
|
private readonly services;
|
|
5731
5749
|
private readonly subContexts;
|
|
5750
|
+
private readonly eventSourceRuntimes;
|
|
5732
5751
|
private readonly parentEventForwarder?;
|
|
5733
5752
|
private readonly timers;
|
|
5734
5753
|
private readonly initialReconnectDelayMs;
|
|
@@ -5737,16 +5756,13 @@ declare class Context {
|
|
|
5737
5756
|
private state;
|
|
5738
5757
|
private startPromise?;
|
|
5739
5758
|
private stopPromise?;
|
|
5740
|
-
private eventSubscription?;
|
|
5741
|
-
private eventStreamTask?;
|
|
5742
|
-
private reconnectTimer?;
|
|
5743
|
-
private resolveReconnectTimer?;
|
|
5744
5759
|
private constructor();
|
|
5745
5760
|
on<K extends keyof EventMap>(type: K, handler: (event: EventMap[K]) => void | Promise<void>): () => void;
|
|
5746
5761
|
install<T extends ParameterList, I extends Injection | undefined, OI extends Injection | undefined>(
|
|
5747
5762
|
plugin: Plugin<T, I, OI>,
|
|
5748
5763
|
...args: T
|
|
5749
5764
|
): void;
|
|
5765
|
+
installEventSource(eventSource: MilkyEventSource): void;
|
|
5750
5766
|
provide<T extends object>(service: ServiceClass<T>, instance: T): void;
|
|
5751
5767
|
resolve<T extends object>(service: ServiceClass<T>): T;
|
|
5752
5768
|
tryResolve<T extends object>(service: ServiceClass<T>): T | undefined;
|
|
@@ -5754,7 +5770,7 @@ declare class Context {
|
|
|
5754
5770
|
fork(name: string, filter?: Filter): Context;
|
|
5755
5771
|
timeout(delayMs: number, callback: () => void | Promise<void>): NodeJS.Timeout;
|
|
5756
5772
|
interval(intervalMs: number, callback: () => void | Promise<void>): NodeJS.Timeout;
|
|
5757
|
-
createSession(message: IncomingMessage): Session;
|
|
5773
|
+
createSession(selfId: number, message: IncomingMessage): Session;
|
|
5758
5774
|
start(): Promise<void>;
|
|
5759
5775
|
stop(): Promise<void>;
|
|
5760
5776
|
private startInternal;
|
|
@@ -5763,7 +5779,7 @@ declare class Context {
|
|
|
5763
5779
|
private assertCanScheduleTimer;
|
|
5764
5780
|
private runTimerCallback;
|
|
5765
5781
|
private clearTimers;
|
|
5766
|
-
private
|
|
5782
|
+
private stopEventSources;
|
|
5767
5783
|
private acceptsParentEvent;
|
|
5768
5784
|
private applyPlugins;
|
|
5769
5785
|
private recursiveApplyPlugins;
|
|
@@ -5777,7 +5793,8 @@ declare class Context {
|
|
|
5777
5793
|
private createUnresolvablePluginError;
|
|
5778
5794
|
private getPluginContext;
|
|
5779
5795
|
private createProxyContextForPlugin;
|
|
5780
|
-
private
|
|
5796
|
+
private startEventSource;
|
|
5797
|
+
private runEventSource;
|
|
5781
5798
|
private waitForReconnectDelay;
|
|
5782
5799
|
private resolveReconnectDelay;
|
|
5783
5800
|
static fromUrl(baseUrl: string | URL, options?: ContextOptions & ContextUrlOptions): Context;
|
|
@@ -5842,7 +5859,9 @@ export {
|
|
|
5842
5859
|
LogMessage,
|
|
5843
5860
|
Logger,
|
|
5844
5861
|
MilkyClient,
|
|
5862
|
+
MilkyEventSource,
|
|
5845
5863
|
MilkyEventSubscription,
|
|
5864
|
+
MilkyWebSocketEventSourceOptions,
|
|
5846
5865
|
Parameter,
|
|
5847
5866
|
ParameterList,
|
|
5848
5867
|
ParamsOf,
|
|
@@ -5860,6 +5879,7 @@ export {
|
|
|
5860
5879
|
TypeInstruction,
|
|
5861
5880
|
combineLogHandlers,
|
|
5862
5881
|
createMilkyClient,
|
|
5882
|
+
createMilkyWebSocketEventSource,
|
|
5863
5883
|
definePlugin,
|
|
5864
5884
|
filter,
|
|
5865
5885
|
implementsESNextDisposable,
|
package/dist/index.mjs
CHANGED
|
@@ -24,37 +24,6 @@ var MilkyClientBase = class {
|
|
|
24
24
|
if (json.status === "failed") throw new Error(`API call ${endpoint} failed with retcode ${json.retcode}: ${json.message}`);
|
|
25
25
|
return json.data;
|
|
26
26
|
}
|
|
27
|
-
async startEvents(onEvent) {
|
|
28
|
-
const ws = new WebSocket(`${this.wsBaseUrl}/event${this.accessToken ? `?access_token=${this.accessToken}` : ""}`);
|
|
29
|
-
let closeSubscription = () => {};
|
|
30
|
-
const closed = new Promise((resolve, reject) => {
|
|
31
|
-
closeSubscription = (error) => {
|
|
32
|
-
if (error) reject(error);
|
|
33
|
-
else resolve();
|
|
34
|
-
};
|
|
35
|
-
});
|
|
36
|
-
ws.addEventListener("message", async (event) => {
|
|
37
|
-
try {
|
|
38
|
-
if (typeof event.data !== "string") throw new Error(`Expected text frame, got ${typeof event.data}`);
|
|
39
|
-
await onEvent(JSON.parse(event.data));
|
|
40
|
-
} catch (error) {
|
|
41
|
-
closeSubscription(error);
|
|
42
|
-
ws.close();
|
|
43
|
-
}
|
|
44
|
-
});
|
|
45
|
-
await new Promise((resolve, reject) => {
|
|
46
|
-
ws.addEventListener("open", () => resolve(), { once: true });
|
|
47
|
-
ws.addEventListener("error", (event) => reject(/* @__PURE__ */ new Error(`WebSocket error: ${event}`)));
|
|
48
|
-
});
|
|
49
|
-
ws.addEventListener("error", (event) => closeSubscription(/* @__PURE__ */ new Error(`WebSocket error: ${event}`)));
|
|
50
|
-
ws.addEventListener("close", () => closeSubscription(), { once: true });
|
|
51
|
-
return {
|
|
52
|
-
closed,
|
|
53
|
-
stop() {
|
|
54
|
-
ws.close();
|
|
55
|
-
}
|
|
56
|
-
};
|
|
57
|
-
}
|
|
58
27
|
};
|
|
59
28
|
function createMilkyClient(...params) {
|
|
60
29
|
const base = new MilkyClientBase(...params);
|
|
@@ -64,6 +33,46 @@ function createMilkyClient(...params) {
|
|
|
64
33
|
} });
|
|
65
34
|
}
|
|
66
35
|
//#endregion
|
|
36
|
+
//#region src/protocol/event.ts
|
|
37
|
+
function createMilkyWebSocketEventSource(baseUrl, options) {
|
|
38
|
+
const normalizedBaseUrl = baseUrl.toString();
|
|
39
|
+
const wsBaseUrl = normalizedBaseUrl.endsWith("/") ? normalizedBaseUrl.slice(0, -1).replace(/^http/, "ws") : normalizedBaseUrl.replace(/^http/, "ws");
|
|
40
|
+
return {
|
|
41
|
+
name: "websocket",
|
|
42
|
+
async start(onEvent) {
|
|
43
|
+
const ws = new WebSocket(`${wsBaseUrl}/event${options?.accessToken ? `?access_token=${options.accessToken}` : ""}`);
|
|
44
|
+
let closeSubscription = () => {};
|
|
45
|
+
const closed = new Promise((resolve, reject) => {
|
|
46
|
+
closeSubscription = (error) => {
|
|
47
|
+
if (error) reject(error);
|
|
48
|
+
else resolve();
|
|
49
|
+
};
|
|
50
|
+
});
|
|
51
|
+
ws.addEventListener("message", async (event) => {
|
|
52
|
+
try {
|
|
53
|
+
if (typeof event.data !== "string") throw new Error(`Expected text frame, got ${typeof event.data}`);
|
|
54
|
+
await onEvent(JSON.parse(event.data));
|
|
55
|
+
} catch (error) {
|
|
56
|
+
closeSubscription(error);
|
|
57
|
+
ws.close();
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
await new Promise((resolve, reject) => {
|
|
61
|
+
ws.addEventListener("open", () => resolve(), { once: true });
|
|
62
|
+
ws.addEventListener("error", (event) => reject(/* @__PURE__ */ new Error(`WebSocket error: ${event}`)));
|
|
63
|
+
});
|
|
64
|
+
ws.addEventListener("error", (event) => closeSubscription(/* @__PURE__ */ new Error(`WebSocket error: ${event}`)));
|
|
65
|
+
ws.addEventListener("close", () => closeSubscription(), { once: true });
|
|
66
|
+
return {
|
|
67
|
+
closed,
|
|
68
|
+
stop() {
|
|
69
|
+
ws.close();
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
//#endregion
|
|
67
76
|
//#region src/protocol/segment.ts
|
|
68
77
|
function msg(strings, ...values) {
|
|
69
78
|
let buffer = "";
|
|
@@ -628,6 +637,7 @@ var Context = class Context {
|
|
|
628
637
|
plugins = [];
|
|
629
638
|
services = /* @__PURE__ */ new Map();
|
|
630
639
|
subContexts = /* @__PURE__ */ new Map();
|
|
640
|
+
eventSourceRuntimes = /* @__PURE__ */ new Map();
|
|
631
641
|
parentEventForwarder;
|
|
632
642
|
timers = /* @__PURE__ */ new Set();
|
|
633
643
|
initialReconnectDelayMs;
|
|
@@ -636,10 +646,6 @@ var Context = class Context {
|
|
|
636
646
|
state = "idle";
|
|
637
647
|
startPromise;
|
|
638
648
|
stopPromise;
|
|
639
|
-
eventSubscription;
|
|
640
|
-
eventStreamTask;
|
|
641
|
-
reconnectTimer;
|
|
642
|
-
resolveReconnectTimer;
|
|
643
649
|
constructor(client, options, name, parent, filter) {
|
|
644
650
|
this.client = client;
|
|
645
651
|
this.initialReconnectDelayMs = options?.reconnect?.initialDelayMs ?? DEFAULT_INITIAL_RECONNECT_DELAY_MS;
|
|
@@ -656,10 +662,10 @@ var Context = class Context {
|
|
|
656
662
|
};
|
|
657
663
|
parent.eventBus.on("*", this.parentEventForwarder);
|
|
658
664
|
}
|
|
659
|
-
this.eventBus.on("message_receive", async ({ data: message }) => {
|
|
665
|
+
this.eventBus.on("message_receive", async ({ self_id, data: message }) => {
|
|
660
666
|
try {
|
|
661
667
|
if (this.state === "stopping" || this.state === "stopped") return;
|
|
662
|
-
await this.router.dispatch(this.createSession(message), message);
|
|
668
|
+
await this.router.dispatch(this.createSession(self_id, message), message);
|
|
663
669
|
} catch (error) {
|
|
664
670
|
this.logger.error(`Error routing command (scene=${message.message_scene} peer=${message.peer_id} sender=${message.sender_id} seq=${message.message_seq})`, error);
|
|
665
671
|
}
|
|
@@ -685,6 +691,11 @@ var Context = class Context {
|
|
|
685
691
|
args
|
|
686
692
|
});
|
|
687
693
|
}
|
|
694
|
+
installEventSource(eventSource) {
|
|
695
|
+
if (this.eventSourceRuntimes.has(eventSource)) return;
|
|
696
|
+
this.eventSourceRuntimes.set(eventSource, {});
|
|
697
|
+
if (this.state === "started") this.startEventSource(eventSource);
|
|
698
|
+
}
|
|
688
699
|
provide(service, instance) {
|
|
689
700
|
if (this.services.has(service)) throw new Error(`Service ${service.name} has already been provided in this context.`);
|
|
690
701
|
if (implementsESNextDisposable(instance) && !isDisposable(instance)) throw new Error(`
|
|
@@ -735,8 +746,9 @@ and implement the dispose method to clean up resources when the context stops.
|
|
|
735
746
|
this.timers.add(interval);
|
|
736
747
|
return interval;
|
|
737
748
|
}
|
|
738
|
-
createSession(message) {
|
|
749
|
+
createSession(selfId, message) {
|
|
739
750
|
return {
|
|
751
|
+
selfId,
|
|
740
752
|
raw: message,
|
|
741
753
|
reply: async (textOrSegments, options) => {
|
|
742
754
|
const actualSegments = [];
|
|
@@ -819,8 +831,10 @@ and implement the dispose method to clean up resources when the context stops.
|
|
|
819
831
|
for (const context of startingContexts) if (context.state === "starting") context.state = "idle";
|
|
820
832
|
throw error;
|
|
821
833
|
}
|
|
822
|
-
for (const { context } of appliedContextPlugins)
|
|
823
|
-
|
|
834
|
+
for (const { context } of appliedContextPlugins) {
|
|
835
|
+
context.state = "started";
|
|
836
|
+
for (const eventSource of context.eventSourceRuntimes.keys()) context.startEventSource(eventSource);
|
|
837
|
+
}
|
|
824
838
|
}
|
|
825
839
|
getState() {
|
|
826
840
|
return this.state;
|
|
@@ -833,7 +847,7 @@ and implement the dispose method to clean up resources when the context stops.
|
|
|
833
847
|
} catch (error) {
|
|
834
848
|
errors.push(error);
|
|
835
849
|
}
|
|
836
|
-
await this.
|
|
850
|
+
await this.stopEventSources(errors);
|
|
837
851
|
if (this.parent && this.parentEventForwarder) this.parent.eventBus.off("*", this.parentEventForwarder);
|
|
838
852
|
for (const service of [...this.services.values()].reverse()) {
|
|
839
853
|
if (!isDisposable(service)) continue;
|
|
@@ -862,20 +876,27 @@ and implement the dispose method to clean up resources when the context stops.
|
|
|
862
876
|
for (const timer of this.timers) clearTimeout(timer);
|
|
863
877
|
this.timers.clear();
|
|
864
878
|
}
|
|
865
|
-
async
|
|
866
|
-
this.
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
879
|
+
async stopEventSources(errors) {
|
|
880
|
+
for (const [_, runtime] of this.eventSourceRuntimes) {
|
|
881
|
+
this.resolveReconnectDelay(runtime);
|
|
882
|
+
const subscription = runtime.subscription;
|
|
883
|
+
if (!subscription) continue;
|
|
884
|
+
try {
|
|
885
|
+
await subscription.stop();
|
|
886
|
+
} catch (error) {
|
|
887
|
+
errors.push(error);
|
|
888
|
+
}
|
|
889
|
+
runtime.subscription = void 0;
|
|
872
890
|
}
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
891
|
+
for (const runtime of this.eventSourceRuntimes.values()) {
|
|
892
|
+
if (!runtime.task) continue;
|
|
893
|
+
try {
|
|
894
|
+
await runtime.task;
|
|
895
|
+
} catch (error) {
|
|
896
|
+
errors.push(error);
|
|
897
|
+
} finally {
|
|
898
|
+
runtime.task = void 0;
|
|
899
|
+
}
|
|
879
900
|
}
|
|
880
901
|
}
|
|
881
902
|
acceptsParentEvent(type, event) {
|
|
@@ -1009,13 +1030,18 @@ and implement the dispose method to clean up resources when the context stops.
|
|
|
1009
1030
|
else return Reflect.get(target, prop, receiver);
|
|
1010
1031
|
} });
|
|
1011
1032
|
}
|
|
1012
|
-
|
|
1033
|
+
startEventSource(eventSource) {
|
|
1034
|
+
const runtime = this.eventSourceRuntimes.get(eventSource);
|
|
1035
|
+
if (!runtime) return;
|
|
1036
|
+
runtime.task = this.runEventSource(eventSource, runtime);
|
|
1037
|
+
}
|
|
1038
|
+
async runEventSource(eventSource, runtime) {
|
|
1013
1039
|
let reconnectDelay = this.initialReconnectDelayMs;
|
|
1014
1040
|
let reconnectAttempt = 1;
|
|
1015
1041
|
while (this.state === "started") {
|
|
1016
1042
|
try {
|
|
1017
|
-
this.logger.debug(`Connecting event
|
|
1018
|
-
const subscription = await
|
|
1043
|
+
this.logger.debug(`Connecting ${eventSource.name ?? "event source"} (attempt=${reconnectAttempt})`);
|
|
1044
|
+
const subscription = await eventSource.start((event) => {
|
|
1019
1045
|
try {
|
|
1020
1046
|
if (this.state !== "started") return;
|
|
1021
1047
|
this.eventBus.emit(event.event_type, event);
|
|
@@ -1027,48 +1053,52 @@ and implement the dispose method to clean up resources when the context stops.
|
|
|
1027
1053
|
await subscription.stop();
|
|
1028
1054
|
break;
|
|
1029
1055
|
}
|
|
1030
|
-
|
|
1031
|
-
this.logger.info("Event
|
|
1056
|
+
runtime.subscription = subscription;
|
|
1057
|
+
this.logger.info(`${eventSource.name ?? "Event source"} connected`);
|
|
1032
1058
|
reconnectDelay = this.initialReconnectDelayMs;
|
|
1033
1059
|
reconnectAttempt = 1;
|
|
1034
1060
|
await subscription.closed;
|
|
1035
|
-
|
|
1061
|
+
if (runtime.subscription === subscription) runtime.subscription = void 0;
|
|
1036
1062
|
if (this.state !== "started") break;
|
|
1037
|
-
this.logger.warn(
|
|
1063
|
+
this.logger.warn(`${eventSource.name ?? "Event source"} disconnected; reconnecting in ${reconnectDelay}ms`);
|
|
1038
1064
|
} catch (error) {
|
|
1039
|
-
this.eventSubscription = void 0;
|
|
1040
1065
|
if (this.state !== "started") break;
|
|
1041
|
-
this.logger.error(`Error connecting event
|
|
1066
|
+
this.logger.error(`Error connecting ${eventSource.name ?? "event source"}; reconnecting in ${reconnectDelay}ms`, error);
|
|
1042
1067
|
}
|
|
1043
|
-
await this.waitForReconnectDelay(reconnectDelay);
|
|
1068
|
+
await this.waitForReconnectDelay(runtime, reconnectDelay);
|
|
1044
1069
|
reconnectDelay = Math.min(reconnectDelay * 2, this.maxReconnectDelayMs);
|
|
1045
1070
|
reconnectAttempt += 1;
|
|
1046
1071
|
}
|
|
1047
1072
|
}
|
|
1048
|
-
waitForReconnectDelay(delay) {
|
|
1073
|
+
waitForReconnectDelay(runtime, delay) {
|
|
1049
1074
|
return new Promise((resolve) => {
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1075
|
+
runtime.resolveReconnectTimer = resolve;
|
|
1076
|
+
runtime.reconnectTimer = setTimeout(() => {
|
|
1077
|
+
runtime.reconnectTimer = void 0;
|
|
1078
|
+
runtime.resolveReconnectTimer = void 0;
|
|
1054
1079
|
resolve();
|
|
1055
1080
|
}, delay);
|
|
1056
1081
|
});
|
|
1057
1082
|
}
|
|
1058
|
-
resolveReconnectDelay() {
|
|
1059
|
-
if (
|
|
1060
|
-
clearTimeout(
|
|
1061
|
-
|
|
1083
|
+
resolveReconnectDelay(runtime) {
|
|
1084
|
+
if (runtime.reconnectTimer) {
|
|
1085
|
+
clearTimeout(runtime.reconnectTimer);
|
|
1086
|
+
runtime.reconnectTimer = void 0;
|
|
1062
1087
|
}
|
|
1063
|
-
const resolve =
|
|
1064
|
-
|
|
1088
|
+
const resolve = runtime.resolveReconnectTimer;
|
|
1089
|
+
runtime.resolveReconnectTimer = void 0;
|
|
1065
1090
|
resolve?.();
|
|
1066
1091
|
}
|
|
1067
1092
|
static fromUrl(baseUrl, options) {
|
|
1068
|
-
|
|
1093
|
+
const context = new Context(createMilkyClient(baseUrl, { accessToken: options?.accessToken }), options);
|
|
1094
|
+
if (options?.installEventSource ?? true) context.installEventSource(createMilkyWebSocketEventSource(baseUrl, { accessToken: options?.accessToken }));
|
|
1095
|
+
return context;
|
|
1069
1096
|
}
|
|
1070
1097
|
static fromClient(client, options) {
|
|
1071
|
-
|
|
1098
|
+
const context = new Context(client, options);
|
|
1099
|
+
const eventSourceLike = client;
|
|
1100
|
+
if (typeof eventSourceLike.start === "function") context.installEventSource(eventSourceLike);
|
|
1101
|
+
return context;
|
|
1072
1102
|
}
|
|
1073
1103
|
};
|
|
1074
1104
|
//#endregion
|
|
@@ -1226,10 +1256,10 @@ function definePlugin(plugin) {
|
|
|
1226
1256
|
//#endregion
|
|
1227
1257
|
//#region src/protocol/types.ts
|
|
1228
1258
|
const milkyVersion = "1.3";
|
|
1229
|
-
const milkyPackageVersion = "1.3.0-rc.
|
|
1259
|
+
const milkyPackageVersion = "1.3.0-rc.2";
|
|
1230
1260
|
//#endregion
|
|
1231
1261
|
//#region src/routing/parameter.ts
|
|
1232
|
-
var Parameter = class {
|
|
1262
|
+
var Parameter = class Parameter {
|
|
1233
1263
|
capturer;
|
|
1234
1264
|
description;
|
|
1235
1265
|
constructor(capturer) {
|
|
@@ -1239,6 +1269,18 @@ var Parameter = class {
|
|
|
1239
1269
|
this.description = description;
|
|
1240
1270
|
return this;
|
|
1241
1271
|
}
|
|
1272
|
+
refine(predicate) {
|
|
1273
|
+
const capturer = this.capturer;
|
|
1274
|
+
const refined = new Parameter({
|
|
1275
|
+
typeInstruction: capturer.typeInstruction,
|
|
1276
|
+
capture(tokenizer) {
|
|
1277
|
+
const value = capturer.capture(tokenizer);
|
|
1278
|
+
if (value === void 0 || predicate(value)) return value;
|
|
1279
|
+
}
|
|
1280
|
+
});
|
|
1281
|
+
refined.description = this.description;
|
|
1282
|
+
return refined;
|
|
1283
|
+
}
|
|
1242
1284
|
};
|
|
1243
1285
|
let param;
|
|
1244
1286
|
(function(_param) {
|
|
@@ -1340,4 +1382,4 @@ let param;
|
|
|
1340
1382
|
_param.segment = segment;
|
|
1341
1383
|
})(param || (param = {}));
|
|
1342
1384
|
//#endregion
|
|
1343
|
-
export { CommandBuilder, Context, Logger, Parameter, Router, combineLogHandlers, createMilkyClient, definePlugin, filter, implementsESNextDisposable, isDisposable, milkyPackageVersion, milkyVersion, msg, param, seg };
|
|
1385
|
+
export { CommandBuilder, Context, Logger, Parameter, Router, combineLogHandlers, createMilkyClient, createMilkyWebSocketEventSource, definePlugin, filter, implementsESNextDisposable, isDisposable, milkyPackageVersion, milkyVersion, msg, param, seg };
|