@antdv-next/x-sdk 0.0.1 → 0.0.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.
Files changed (54) hide show
  1. package/dist/_util/resolveMaybeRef.d.ts +2 -0
  2. package/dist/_util/resolveMaybeRef.js +7 -0
  3. package/dist/_util/types.js +0 -0
  4. package/dist/chat-providers/AbstractChatProvider.d.ts +2 -2
  5. package/dist/chat-providers/AbstractChatProvider.js +42 -0
  6. package/dist/chat-providers/DeepSeekChatProvider.d.ts +2 -2
  7. package/dist/chat-providers/DeepSeekChatProvider.js +59 -0
  8. package/dist/chat-providers/DefaultChatProvider.d.ts +2 -2
  9. package/dist/chat-providers/DefaultChatProvider.js +26 -0
  10. package/dist/chat-providers/OpenAIChatProvider.d.ts +2 -2
  11. package/dist/chat-providers/OpenAIChatProvider.js +49 -0
  12. package/dist/chat-providers/index.js +4 -1
  13. package/dist/index.d.ts +1 -1
  14. package/dist/index.js +7 -3
  15. package/dist/node_modules/vitest/dist/@vitest/expect/index.js +1456 -0
  16. package/dist/node_modules/vitest/dist/@vitest/pretty-format/index.js +884 -0
  17. package/dist/node_modules/vitest/dist/@vitest/runner/chunk-artifact.js +1543 -0
  18. package/dist/node_modules/vitest/dist/@vitest/snapshot/index.js +660 -0
  19. package/dist/node_modules/vitest/dist/@vitest/spy/index.js +384 -0
  20. package/dist/node_modules/vitest/dist/@vitest/utils/chunk-pathe.M-eThtNZ.js +80 -0
  21. package/dist/node_modules/vitest/dist/@vitest/utils/diff.js +1304 -0
  22. package/dist/node_modules/vitest/dist/@vitest/utils/display.js +556 -0
  23. package/dist/node_modules/vitest/dist/@vitest/utils/error.js +27 -0
  24. package/dist/node_modules/vitest/dist/@vitest/utils/helpers.js +179 -0
  25. package/dist/node_modules/vitest/dist/@vitest/utils/offset.js +25 -0
  26. package/dist/node_modules/vitest/dist/@vitest/utils/serialize.js +75 -0
  27. package/dist/node_modules/vitest/dist/@vitest/utils/source-map.js +371 -0
  28. package/dist/node_modules/vitest/dist/@vitest/utils/timers.js +35 -0
  29. package/dist/node_modules/vitest/dist/chunks/_commonjsHelpers.D26ty3Ew.js +4 -0
  30. package/dist/node_modules/vitest/dist/chunks/rpc.MzXet3jl.js +50 -0
  31. package/dist/node_modules/vitest/dist/chunks/test.CBQUpOM3.js +2640 -0
  32. package/dist/node_modules/vitest/dist/chunks/utils.BX5Fg8C4.js +42 -0
  33. package/dist/node_modules/vitest/dist/vendor/chai.js +2872 -0
  34. package/dist/node_modules/vitest/dist/vendor/magic-string.js +1009 -0
  35. package/dist/node_modules/vitest/dist/vendor/tinyrainbow.js +84 -0
  36. package/dist/x-chat/__tests__/index.test.d.ts +1 -0
  37. package/dist/x-chat/__tests__/index.test.js +257 -0
  38. package/dist/x-chat/index.d.ts +14 -23
  39. package/dist/x-chat/index.js +83 -66
  40. package/dist/x-chat/store.d.ts +2 -0
  41. package/dist/{store-C1diHqNH.js → x-chat/store.js} +15 -9
  42. package/dist/x-conversations/__tests__/index.test.d.ts +1 -0
  43. package/dist/x-conversations/__tests__/index.test.js +36 -0
  44. package/dist/x-conversations/index.d.ts +4 -4
  45. package/dist/x-conversations/index.js +37 -1
  46. package/dist/{x-conversations-BrKWhj5r.js → x-conversations/store.js} +2 -31
  47. package/dist/x-request/__tests__/index.test.d.ts +1 -0
  48. package/dist/x-request/__tests__/index.test.js +90 -0
  49. package/dist/x-request/index.d.ts +36 -11
  50. package/dist/x-request/index.js +246 -1
  51. package/dist/x-request/x-fetch.js +18 -0
  52. package/package.json +1 -1
  53. package/dist/chat-providers-5x9Va7p5.js +0 -167
  54. package/dist/x-request-BSFGaKND.js +0 -234
@@ -20,10 +20,12 @@ export declare class ChatMessagesStore<T extends {
20
20
  private pendingEmit;
21
21
  private readonly throttleInterval;
22
22
  private isDestroyed;
23
+ private defaultMessagesLoader;
23
24
  private emitListeners;
24
25
  private throttledEmitListeners;
25
26
  constructor(defaultMessages: () => Promise<T[]>, conversationKey?: ConversationKey);
26
27
  private initializeMessages;
28
+ refreshDefaultMessages: () => boolean;
27
29
  private setSnapshotResult;
28
30
  private setMessagesInternal;
29
31
  setMessages: (messages: T[] | ((ori: T[]) => T[])) => boolean;
@@ -25,6 +25,7 @@ var ChatMessagesStore = class {
25
25
  pendingEmit = false;
26
26
  throttleInterval = 50;
27
27
  isDestroyed = false;
28
+ defaultMessagesLoader;
28
29
  emitListeners() {
29
30
  this.listeners.forEach((listener) => {
30
31
  listener();
@@ -44,27 +45,32 @@ var ChatMessagesStore = class {
44
45
  } else this.pendingEmit = true;
45
46
  }
46
47
  constructor(defaultMessages, conversationKey) {
47
- this.initializeMessages(defaultMessages, (value) => {
48
- this.setSnapshotResult("isDefaultMessagesRequesting", value);
49
- this.emitListeners();
50
- });
48
+ this.defaultMessagesLoader = defaultMessages;
49
+ this.initializeMessages();
51
50
  if (conversationKey) {
52
51
  this.conversationKey = conversationKey;
53
52
  chatMessagesStoreHelper.set(this.conversationKey, this);
54
53
  }
55
54
  }
56
- async initializeMessages(defaultMessages, setDefaultMessagesRequesting) {
55
+ async initializeMessages() {
57
56
  try {
58
- setDefaultMessagesRequesting(true);
59
- const messages = await defaultMessages();
57
+ this.setSnapshotResult("isDefaultMessagesRequesting", true);
58
+ this.emitListeners();
59
+ const messages = await this.defaultMessagesLoader();
60
60
  if (!this.isDestroyed) this.setMessagesInternal(messages, false);
61
61
  } catch (error) {
62
62
  console.warn("Failed to initialize messages:", error);
63
63
  if (!this.isDestroyed) this.setMessagesInternal([], false);
64
64
  } finally {
65
- setDefaultMessagesRequesting(false);
65
+ this.setSnapshotResult("isDefaultMessagesRequesting", false);
66
+ this.emitListeners();
66
67
  }
67
68
  }
69
+ refreshDefaultMessages = () => {
70
+ if (this.isDestroyed) return false;
71
+ this.initializeMessages();
72
+ return true;
73
+ };
68
74
  setSnapshotResult = (key, value) => {
69
75
  this.snapshotResult = {
70
76
  ...this.snapshotResult,
@@ -142,4 +148,4 @@ var ChatMessagesStore = class {
142
148
  };
143
149
  };
144
150
  //#endregion
145
- export { chatMessagesStoreHelper as n, ChatMessagesStore as t };
151
+ export { ChatMessagesStore, chatMessagesStoreHelper };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,36 @@
1
+ import useXConversations from "../index.js";
2
+ import { describe, it } from "../../node_modules/vitest/dist/@vitest/runner/chunk-artifact.js";
3
+ import { globalExpect } from "../../node_modules/vitest/dist/chunks/test.CBQUpOM3.js";
4
+ import { effectScope, nextTick, ref } from "vue";
5
+ //#region src/x-conversations/__tests__/index.test.ts
6
+ describe("useXConversations", () => {
7
+ it("syncs default conversations and active key from refs", async () => {
8
+ const defaultConversations = ref([{
9
+ key: "session_1",
10
+ label: "Session 1"
11
+ }, {
12
+ key: "session_2",
13
+ label: "Session 2"
14
+ }]);
15
+ const defaultActiveConversationKey = ref("session_1");
16
+ const scope = effectScope();
17
+ const conversationsHandler = scope.run(() => useXConversations({
18
+ defaultConversations,
19
+ defaultActiveConversationKey
20
+ }));
21
+ globalExpect(conversationsHandler).toBeTruthy();
22
+ if (!conversationsHandler) return;
23
+ globalExpect(conversationsHandler.conversations.value.map((item) => item.key)).toEqual(["session_1", "session_2"]);
24
+ globalExpect(conversationsHandler.activeConversationKey.value).toBe("session_1");
25
+ defaultConversations.value = [{
26
+ key: "session_3",
27
+ label: "Session 3"
28
+ }];
29
+ defaultActiveConversationKey.value = "session_3";
30
+ await nextTick();
31
+ globalExpect(conversationsHandler.conversations.value.map((item) => item.key)).toEqual(["session_3"]);
32
+ globalExpect(conversationsHandler.activeConversationKey.value).toBe("session_3");
33
+ scope.stop();
34
+ });
35
+ });
36
+ //#endregion
@@ -1,10 +1,11 @@
1
+ import { MaybeRef } from 'vue';
1
2
  import { AnyObject } from '../_util/types';
2
3
  export interface ConversationData extends AnyObject {
3
4
  key: string;
4
5
  }
5
- interface XConversationConfig {
6
- defaultConversations?: ConversationData[];
7
- defaultActiveConversationKey?: string;
6
+ export interface XConversationConfig {
7
+ defaultConversations?: MaybeRef<ConversationData[]>;
8
+ defaultActiveConversationKey?: MaybeRef<string>;
8
9
  }
9
10
  export default function useXConversations(config: XConversationConfig): {
10
11
  conversations: import('vue').ShallowRef<ConversationData[], ConversationData[]>;
@@ -17,4 +18,3 @@ export default function useXConversations(config: XConversationConfig): {
17
18
  setConversations: (list: ConversationData[]) => boolean;
18
19
  getMessages: (key: ConversationData["key"]) => any[] | undefined;
19
20
  };
20
- export {};
@@ -1,2 +1,38 @@
1
- import { t as useXConversations } from "../x-conversations-BrKWhj5r.js";
1
+ import resolveMaybeRef from "../_util/resolveMaybeRef.js";
2
+ import { ConversationStore } from "./store.js";
3
+ import { isRef, onScopeDispose, ref, shallowRef, watch } from "vue";
4
+ //#region src/x-conversations/index.ts
5
+ function useXConversations(config) {
6
+ const store = new ConversationStore(resolveMaybeRef(config?.defaultConversations) || [], resolveMaybeRef(config?.defaultActiveConversationKey) || "");
7
+ const conversations = shallowRef(store.getSnapshot());
8
+ const activeConversationKey = ref(store.getActiveConversationKey());
9
+ const syncStore = () => {
10
+ conversations.value = store.getSnapshot();
11
+ activeConversationKey.value = store.getActiveConversationKey();
12
+ };
13
+ const unsubscribe = store.subscribe(syncStore);
14
+ syncStore();
15
+ if (config?.defaultConversations && isRef(config.defaultConversations)) watch(config.defaultConversations, (list) => {
16
+ store.setConversations(list || []);
17
+ }, { deep: true });
18
+ if (config?.defaultActiveConversationKey && isRef(config.defaultActiveConversationKey)) watch(config.defaultActiveConversationKey, (key) => {
19
+ if (typeof key === "string") store.setActiveConversationKey(key);
20
+ });
21
+ onScopeDispose(() => {
22
+ unsubscribe();
23
+ store.destroy();
24
+ });
25
+ return {
26
+ conversations,
27
+ activeConversationKey,
28
+ setActiveConversationKey: store.setActiveConversationKey,
29
+ addConversation: store.addConversation,
30
+ removeConversation: store.removeConversation,
31
+ setConversation: store.setConversation,
32
+ getConversation: store.getConversation,
33
+ setConversations: store.setConversations,
34
+ getMessages: store.getMessages
35
+ };
36
+ }
37
+ //#endregion
2
38
  export { useXConversations as default };
@@ -1,5 +1,4 @@
1
- import { n as chatMessagesStoreHelper } from "./store-C1diHqNH.js";
2
- import { onScopeDispose, ref, shallowRef } from "vue";
1
+ import { chatMessagesStoreHelper } from "../x-chat/store.js";
3
2
  //#region src/x-conversations/store.ts
4
3
  var conversationStoreHelper = {
5
4
  _allConversationStores: /* @__PURE__ */ new Map(),
@@ -91,32 +90,4 @@ var ConversationStore = class {
91
90
  };
92
91
  };
93
92
  //#endregion
94
- //#region src/x-conversations/index.ts
95
- function useXConversations(config) {
96
- const store = new ConversationStore(config?.defaultConversations || [], config?.defaultActiveConversationKey || "");
97
- const conversations = shallowRef(store.getSnapshot());
98
- const activeConversationKey = ref(store.getActiveConversationKey());
99
- const syncStore = () => {
100
- conversations.value = store.getSnapshot();
101
- activeConversationKey.value = store.getActiveConversationKey();
102
- };
103
- const unsubscribe = store.subscribe(syncStore);
104
- syncStore();
105
- onScopeDispose(() => {
106
- unsubscribe();
107
- store.destroy();
108
- });
109
- return {
110
- conversations,
111
- activeConversationKey,
112
- setActiveConversationKey: store.setActiveConversationKey,
113
- addConversation: store.addConversation,
114
- removeConversation: store.removeConversation,
115
- setConversation: store.setConversation,
116
- getConversation: store.getConversation,
117
- setConversations: store.setConversations,
118
- getMessages: store.getMessages
119
- };
120
- }
121
- //#endregion
122
- export { useXConversations as t };
93
+ export { ConversationStore, conversationStoreHelper };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,90 @@
1
+ import XRequest from "../index.js";
2
+ import { describe, it } from "../../node_modules/vitest/dist/@vitest/runner/chunk-artifact.js";
3
+ import { globalExpect, vi } from "../../node_modules/vitest/dist/chunks/test.CBQUpOM3.js";
4
+ import { ref } from "vue";
5
+ //#region src/x-request/__tests__/index.test.ts
6
+ describe("XRequest", () => {
7
+ it("uses reactive baseURL / params / headers refs on each run", async () => {
8
+ const baseURL = ref("https://example.com/api/v1");
9
+ const params = ref({ a: 1 });
10
+ const headers = ref({ Authorization: "Bearer token-1" });
11
+ const fetchMock = vi.fn(async (_url, _options) => {
12
+ return new Response(JSON.stringify({ success: true }), {
13
+ status: 200,
14
+ headers: { "content-type": "application/json" }
15
+ });
16
+ });
17
+ const request = XRequest(baseURL, {
18
+ manual: true,
19
+ params,
20
+ headers,
21
+ fetch: fetchMock
22
+ });
23
+ request.run({ b: 2 });
24
+ await request.asyncHandler;
25
+ globalExpect(fetchMock).toHaveBeenCalledTimes(1);
26
+ const firstCall = fetchMock.mock.calls[0];
27
+ const firstUrl = firstCall[0];
28
+ const firstOptions = firstCall[1];
29
+ globalExpect(firstUrl).toBe("https://example.com/api/v1");
30
+ globalExpect(JSON.parse(firstOptions.body)).toEqual({
31
+ a: 1,
32
+ b: 2
33
+ });
34
+ globalExpect(firstOptions.headers.Authorization).toBe("Bearer token-1");
35
+ baseURL.value = "https://example.com/api/v2";
36
+ params.value = { a: 3 };
37
+ headers.value = { Authorization: "Bearer token-2" };
38
+ request.run({ b: 4 });
39
+ await request.asyncHandler;
40
+ globalExpect(fetchMock).toHaveBeenCalledTimes(2);
41
+ const secondCall = fetchMock.mock.calls[1];
42
+ const secondUrl = secondCall[0];
43
+ const secondOptions = secondCall[1];
44
+ globalExpect(secondUrl).toBe("https://example.com/api/v2");
45
+ globalExpect(JSON.parse(secondOptions.body)).toEqual({
46
+ a: 3,
47
+ b: 4
48
+ });
49
+ globalExpect(secondOptions.headers.Authorization).toBe("Bearer token-2");
50
+ });
51
+ it("tracks reactive manual option", () => {
52
+ const manual = ref(true);
53
+ const request = XRequest("https://example.com/manual", {
54
+ manual,
55
+ fetch: vi.fn()
56
+ });
57
+ globalExpect(request.manual).toBe(true);
58
+ manual.value = false;
59
+ globalExpect(request.manual).toBe(false);
60
+ manual.value = true;
61
+ globalExpect(request.manual).toBe(true);
62
+ });
63
+ it("supports plain middlewares object", async () => {
64
+ const onRequest = vi.fn(async (baseURL, options) => {
65
+ return [`${baseURL.toString()}?mw=1`, options];
66
+ });
67
+ const onResponse = vi.fn(async (response) => response);
68
+ const fetchMock = vi.fn(async (_url) => {
69
+ return new Response(JSON.stringify({ success: true }), {
70
+ status: 200,
71
+ headers: { "content-type": "application/json" }
72
+ });
73
+ });
74
+ const request = XRequest("https://example.com/middlewares", {
75
+ manual: true,
76
+ fetch: fetchMock,
77
+ middlewares: {
78
+ onRequest,
79
+ onResponse
80
+ }
81
+ });
82
+ request.run();
83
+ await request.asyncHandler;
84
+ globalExpect(onRequest).toHaveBeenCalledTimes(1);
85
+ globalExpect(onResponse).toHaveBeenCalledTimes(1);
86
+ globalExpect(fetchMock).toHaveBeenCalledTimes(1);
87
+ globalExpect(fetchMock.mock.calls[0]?.[0]).toBe("https://example.com/middlewares?mw=1");
88
+ });
89
+ });
90
+ //#endregion
@@ -1,3 +1,4 @@
1
+ import { MaybeRef } from 'vue';
1
2
  import { AnyObject } from '../_util/types';
2
3
  import { MessageInfo, SimpleType } from '../x-chat';
3
4
  import { SSEOutput, XStreamOptions } from '../x-stream';
@@ -23,30 +24,49 @@ export interface XRequestOptions<Input = AnyObject, Output = SSEOutput, ChatMess
23
24
  retryInterval?: number;
24
25
  retryTimes?: number;
25
26
  }
26
- export type XRequestGlobalOptions<Input, Output> = Pick<XRequestOptions<Input, Output>, "headers" | "timeout" | "streamTimeout" | "middlewares" | "fetch" | "transformStream" | "manual">;
27
- export type XRequestFunction<Input = AnyObject, Output = SSEOutput> = (baseURL: string, options?: XRequestOptions<Input, Output>) => XRequestClass<Input, Output>;
27
+ export type XRequestConfigOptions<Input = AnyObject, Output = SSEOutput, ChatMessage extends SimpleType = any> = Omit<XRequestOptions<Input, Output, ChatMessage>, "callbacks" | "params" | "headers" | "timeout" | "streamTimeout" | "fetch" | "middlewares" | "transformStream" | "streamSeparator" | "partSeparator" | "kvSeparator" | "manual" | "retryInterval" | "retryTimes"> & {
28
+ callbacks?: XRequestCallbacks<Output, ChatMessage>;
29
+ params?: MaybeRef<Partial<Input>>;
30
+ headers?: MaybeRef<Record<string, string>>;
31
+ timeout?: MaybeRef<number>;
32
+ streamTimeout?: MaybeRef<number>;
33
+ fetch?: (baseURL: Parameters<typeof fetch>[0], options: XRequestOptions<Input, Output>) => Promise<Response>;
34
+ middlewares?: XFetchMiddlewares<Input, Output>;
35
+ transformStream?: XStreamOptions<Output>["transformStream"] | ((baseURL: string, responseHeaders: Headers) => XStreamOptions<Output>["transformStream"]);
36
+ streamSeparator?: MaybeRef<string>;
37
+ partSeparator?: MaybeRef<string>;
38
+ kvSeparator?: MaybeRef<string>;
39
+ manual?: MaybeRef<boolean>;
40
+ retryInterval?: MaybeRef<number>;
41
+ retryTimes?: MaybeRef<number>;
42
+ };
43
+ export type XRequestGlobalOptions<Input, Output> = Pick<XRequestConfigOptions<Input, Output>, "headers" | "timeout" | "streamTimeout" | "middlewares" | "fetch" | "transformStream" | "manual">;
44
+ export type XRequestFunction<Input = AnyObject, Output = SSEOutput> = (baseURL: MaybeRef<string>, options?: XRequestConfigOptions<Input, Output>) => XRequestClass<Input, Output>;
45
+ export interface XRequestReactiveState {
46
+ isTimeout: boolean;
47
+ isStreamTimeout: boolean;
48
+ isRequesting: boolean;
49
+ }
28
50
  export declare function setXRequestGlobalOptions<Input, Output>(options: XRequestGlobalOptions<Input, Output>): void;
29
51
  export declare abstract class AbstractXRequestClass<Input, Output, ChatMessage extends SimpleType = any> {
30
- baseURL: string;
31
- options: XRequestOptions<Input, Output, ChatMessage>;
32
- constructor(baseURL: string, options?: XRequestOptions<Input, Output, ChatMessage>);
52
+ baseURL: MaybeRef<string>;
53
+ options: XRequestConfigOptions<Input, Output, ChatMessage>;
54
+ constructor(baseURL: MaybeRef<string>, options?: XRequestConfigOptions<Input, Output, ChatMessage>);
33
55
  abstract get asyncHandler(): Promise<any>;
34
56
  abstract get isTimeout(): boolean;
35
57
  abstract get isStreamTimeout(): boolean;
36
58
  abstract get isRequesting(): boolean;
37
59
  abstract get manual(): boolean;
60
+ abstract get state(): Readonly<XRequestReactiveState>;
38
61
  abstract run(params?: Input): void;
39
62
  abstract abort(): void;
40
63
  }
41
64
  export declare class XRequestClass<Input = AnyObject, Output = SSEOutput, ChatMessage extends SimpleType = any> extends AbstractXRequestClass<Input, Output, ChatMessage> {
42
65
  private _asyncHandler;
43
66
  private timeoutHandler;
44
- private _isTimeout;
45
67
  private streamTimeoutHandler;
46
- private _isStreamTimeout;
47
68
  private abortController;
48
- private _isRequesting;
49
- private _manual;
69
+ private _state;
50
70
  private lastManualParams?;
51
71
  private retryTimes;
52
72
  private retryTimer;
@@ -58,7 +78,12 @@ export declare class XRequestClass<Input = AnyObject, Output = SSEOutput, ChatMe
58
78
  private set isStreamTimeout(value);
59
79
  get isRequesting(): boolean;
60
80
  get manual(): boolean;
61
- constructor(baseURL: string, options?: XRequestOptions<Input, Output, ChatMessage>);
81
+ get state(): {
82
+ readonly isTimeout: boolean;
83
+ readonly isStreamTimeout: boolean;
84
+ readonly isRequesting: boolean;
85
+ };
86
+ constructor(baseURL: MaybeRef<string>, options?: XRequestConfigOptions<Input, Output, ChatMessage>);
62
87
  run(params?: Input): boolean;
63
88
  abort(): void;
64
89
  private init;
@@ -70,5 +95,5 @@ export declare class XRequestClass<Input = AnyObject, Output = SSEOutput, ChatMe
70
95
  private jsonResponseHandler;
71
96
  private resetRetry;
72
97
  }
73
- declare function XRequest<Input = AnyObject, Output = SSEOutput, ChatMessage extends SimpleType = any>(baseURL: string, options?: XRequestOptions<Input, Output, ChatMessage>): AbstractXRequestClass<Input, Output, ChatMessage>;
98
+ declare function XRequest<Input = AnyObject, Output = SSEOutput, ChatMessage extends SimpleType = any>(baseURL: MaybeRef<string>, options?: XRequestConfigOptions<Input, Output, ChatMessage>): AbstractXRequestClass<Input, Output, ChatMessage>;
74
99
  export default XRequest;
@@ -1,2 +1,247 @@
1
- import { i as setXRequestGlobalOptions, n as XRequest, r as XRequestClass, t as AbstractXRequestClass } from "../x-request-BSFGaKND.js";
1
+ import resolveMaybeRef from "../_util/resolveMaybeRef.js";
2
+ import XStream from "../x-stream/index.js";
3
+ import XFetch from "./x-fetch.js";
4
+ import { reactive, readonly } from "vue";
5
+ //#region src/x-request/index.ts
6
+ var globalOptions = {
7
+ manual: false,
8
+ headers: { "Content-Type": "application/json" }
9
+ };
10
+ function setXRequestGlobalOptions(options) {
11
+ Object.assign(globalOptions, options);
12
+ }
13
+ var LastEventId = "Last-Event-ID";
14
+ var AbstractXRequestClass = class {
15
+ baseURL;
16
+ options;
17
+ constructor(baseURL, options) {
18
+ const resolvedBaseURL = resolveMaybeRef(baseURL);
19
+ if (!resolvedBaseURL || typeof resolvedBaseURL !== "string") throw new Error("The baseURL is not valid!");
20
+ this.baseURL = baseURL;
21
+ this.options = options || {};
22
+ }
23
+ };
24
+ var XRequestClass = class extends AbstractXRequestClass {
25
+ _asyncHandler;
26
+ timeoutHandler;
27
+ streamTimeoutHandler;
28
+ abortController;
29
+ _state = reactive({
30
+ isTimeout: false,
31
+ isStreamTimeout: false,
32
+ isRequesting: false
33
+ });
34
+ lastManualParams;
35
+ retryTimes = 0;
36
+ retryTimer;
37
+ lastEventId = void 0;
38
+ get asyncHandler() {
39
+ return this._asyncHandler;
40
+ }
41
+ get isTimeout() {
42
+ return this._state.isTimeout;
43
+ }
44
+ set isTimeout(value) {
45
+ this._state.isTimeout = value;
46
+ }
47
+ get isStreamTimeout() {
48
+ return this._state.isStreamTimeout;
49
+ }
50
+ set isStreamTimeout(value) {
51
+ this._state.isStreamTimeout = value;
52
+ }
53
+ get isRequesting() {
54
+ return this._state.isRequesting;
55
+ }
56
+ get manual() {
57
+ const localManual = resolveMaybeRef(this.options.manual);
58
+ if (typeof localManual === "boolean") return localManual;
59
+ const globalManual = resolveMaybeRef(globalOptions.manual);
60
+ if (typeof globalManual === "boolean") return globalManual;
61
+ return false;
62
+ }
63
+ get state() {
64
+ return readonly(this._state);
65
+ }
66
+ constructor(baseURL, options) {
67
+ super(baseURL, options);
68
+ if (!this.manual) this.init();
69
+ }
70
+ run(params) {
71
+ if (this.manual) {
72
+ this.resetRetry();
73
+ this.lastManualParams = params;
74
+ this.init(params);
75
+ return true;
76
+ }
77
+ console.warn("The request is not manual, so it cannot be run!");
78
+ return false;
79
+ }
80
+ abort() {
81
+ clearTimeout(this.timeoutHandler);
82
+ clearTimeout(this.streamTimeoutHandler);
83
+ this.abortController.abort();
84
+ }
85
+ init(extraParams, extraHeaders) {
86
+ const currentBaseURL = resolveMaybeRef(this.baseURL);
87
+ if (!currentBaseURL || typeof currentBaseURL !== "string") throw new Error("The baseURL is not valid!");
88
+ this.abortController = new AbortController();
89
+ this.isTimeout = false;
90
+ this.isStreamTimeout = false;
91
+ const { callbacks: sourceCallbacks, params: sourceParams, headers: sourceHeaders, transformStream: sourceTransformStream, fetch: sourceFetch, timeout: sourceTimeout, streamTimeout: sourceStreamTimeout, middlewares: sourceMiddlewares, streamSeparator: sourceStreamSeparator, partSeparator: sourcePartSeparator, kvSeparator: sourceKvSeparator, manual: _sourceManual, retryInterval: sourceRetryInterval, retryTimes: sourceRetryTimes, ...otherOptions } = this.options;
92
+ const callbacks = sourceCallbacks;
93
+ const params = resolveMaybeRef(sourceParams);
94
+ const headers = resolveMaybeRef(sourceHeaders) || {};
95
+ const transformStream = sourceTransformStream;
96
+ const fetch = sourceFetch;
97
+ const timeout = resolveMaybeRef(sourceTimeout);
98
+ const streamTimeout = resolveMaybeRef(sourceStreamTimeout);
99
+ const middlewares = sourceMiddlewares;
100
+ const streamSeparator = resolveMaybeRef(sourceStreamSeparator);
101
+ const partSeparator = resolveMaybeRef(sourcePartSeparator);
102
+ const kvSeparator = resolveMaybeRef(sourceKvSeparator);
103
+ const retryInterval = resolveMaybeRef(sourceRetryInterval);
104
+ const retryTimes = resolveMaybeRef(sourceRetryTimes);
105
+ const globalHeaders = resolveMaybeRef(globalOptions.headers) || {};
106
+ const margeHeaders = Object.assign({}, globalHeaders, headers, extraHeaders || {});
107
+ const requestInit = {
108
+ ...otherOptions,
109
+ method: "POST",
110
+ body: JSON.stringify({
111
+ ...params,
112
+ ...extraParams
113
+ }),
114
+ params: {
115
+ ...params,
116
+ ...extraParams
117
+ },
118
+ headers: margeHeaders,
119
+ signal: this.abortController.signal,
120
+ middlewares
121
+ };
122
+ if (timeout && timeout > 0) this.timeoutHandler = setTimeout(() => {
123
+ this.isTimeout = true;
124
+ this.finishRequest();
125
+ callbacks?.onError?.(/* @__PURE__ */ new Error("TimeoutError"));
126
+ }, timeout);
127
+ this.startRequest();
128
+ this._asyncHandler = XFetch(currentBaseURL, {
129
+ fetch,
130
+ ...requestInit
131
+ }).then(async (response) => {
132
+ clearTimeout(this.timeoutHandler);
133
+ if (this.isTimeout) return;
134
+ if (transformStream) {
135
+ let transformer = transformStream;
136
+ if (typeof transformStream === "function") transformer = transformStream(currentBaseURL, response.headers);
137
+ await this.customResponseHandler(response, callbacks, transformer, streamTimeout, streamSeparator, partSeparator, kvSeparator);
138
+ return;
139
+ }
140
+ const contentType = response.headers.get("content-type") || "";
141
+ switch (contentType.split(";")[0].trim()) {
142
+ case "text/event-stream":
143
+ await this.sseResponseHandler(response, callbacks, streamTimeout, streamSeparator, partSeparator, kvSeparator);
144
+ break;
145
+ case "application/json":
146
+ await this.jsonResponseHandler(response, callbacks);
147
+ break;
148
+ default: throw new Error(`The response content-type: ${contentType} is not support!`);
149
+ }
150
+ }).catch((error) => {
151
+ clearTimeout(this.timeoutHandler);
152
+ this.finishRequest();
153
+ const err = error instanceof Error || error instanceof DOMException ? error : /* @__PURE__ */ new Error("Unknown error!");
154
+ const returnOfOnError = callbacks?.onError?.(err);
155
+ if (err.name !== "AbortError") {
156
+ const actualRetryInterval = typeof returnOfOnError === "number" ? returnOfOnError : retryInterval;
157
+ if (actualRetryInterval && actualRetryInterval > 0) {
158
+ if (typeof retryTimes === "number" && this.retryTimes >= retryTimes) return;
159
+ clearTimeout(this.retryTimer);
160
+ this.retryTimer = setTimeout(() => {
161
+ const extraHeaders = {};
162
+ if (typeof this.lastEventId !== "undefined") extraHeaders[LastEventId] = this.lastEventId;
163
+ this.init(this.lastManualParams, extraHeaders);
164
+ }, actualRetryInterval);
165
+ this.retryTimes = this.retryTimes + 1;
166
+ }
167
+ }
168
+ });
169
+ }
170
+ startRequest() {
171
+ this._state.isRequesting = true;
172
+ }
173
+ finishRequest() {
174
+ this._state.isRequesting = false;
175
+ }
176
+ customResponseHandler = async (response, callbacks, transformStream, streamTimeout, streamSeparator, partSeparator, kvSeparator) => {
177
+ const stream = XStream({
178
+ readableStream: response.body,
179
+ transformStream,
180
+ streamSeparator,
181
+ partSeparator,
182
+ kvSeparator
183
+ });
184
+ await this.processStream(stream, response, callbacks, streamTimeout);
185
+ };
186
+ sseResponseHandler = async (response, callbacks, streamTimeout, streamSeparator, partSeparator, kvSeparator) => {
187
+ const stream = XStream({
188
+ readableStream: response.body,
189
+ streamSeparator,
190
+ partSeparator,
191
+ kvSeparator
192
+ });
193
+ await this.processStream(stream, response, callbacks, streamTimeout);
194
+ };
195
+ async processStream(stream, response, callbacks, streamTimeout) {
196
+ const chunks = [];
197
+ const iterator = stream[Symbol.asyncIterator]();
198
+ let result;
199
+ do {
200
+ if (streamTimeout) this.streamTimeoutHandler = setTimeout(() => {
201
+ this.isStreamTimeout = true;
202
+ this.finishRequest();
203
+ callbacks?.onError?.(/* @__PURE__ */ new Error("StreamTimeoutError"), void 0, response.headers);
204
+ }, streamTimeout);
205
+ result = await iterator.next();
206
+ clearTimeout(this.streamTimeoutHandler);
207
+ if (this.isStreamTimeout) break;
208
+ if (result.value) {
209
+ chunks.push(result.value);
210
+ callbacks?.onUpdate?.(result.value, response.headers);
211
+ if (typeof result?.value?.id !== "undefined") this.lastEventId = result.value.id;
212
+ }
213
+ } while (!result.done);
214
+ if (streamTimeout) {
215
+ clearTimeout(this.streamTimeoutHandler);
216
+ if (this.isStreamTimeout) {
217
+ this.finishRequest();
218
+ return;
219
+ }
220
+ }
221
+ this.finishRequest();
222
+ callbacks?.onSuccess?.(chunks, response.headers);
223
+ }
224
+ jsonResponseHandler = async (response, callbacks) => {
225
+ const chunk = await response.json();
226
+ if (chunk?.success === false) {
227
+ this.finishRequest();
228
+ const error = new Error(chunk.message || "System error");
229
+ error.name = chunk.name || "SystemError";
230
+ callbacks?.onError?.(error, chunk, response.headers);
231
+ } else {
232
+ callbacks?.onUpdate?.(chunk, response.headers);
233
+ this.finishRequest();
234
+ callbacks?.onSuccess?.([chunk], response.headers);
235
+ }
236
+ };
237
+ resetRetry() {
238
+ clearTimeout(this.retryTimer);
239
+ this.retryTimes = 0;
240
+ this.lastEventId = void 0;
241
+ }
242
+ };
243
+ function XRequest(baseURL, options) {
244
+ return new XRequestClass(baseURL, options);
245
+ }
246
+ //#endregion
2
247
  export { AbstractXRequestClass, XRequestClass, XRequest as default, setXRequestGlobalOptions };
@@ -0,0 +1,18 @@
1
+ //#region src/x-request/x-fetch.ts
2
+ var XFetch = async (baseURL, options) => {
3
+ const { fetch: fetchFn = globalThis.fetch, middlewares = {}, ...requestInit } = options;
4
+ if (typeof fetchFn !== "function") throw new Error("The options.fetch must be a typeof fetch function!");
5
+ let fetchArgs = [baseURL, requestInit];
6
+ if (typeof middlewares.onRequest === "function") fetchArgs = await middlewares.onRequest(...fetchArgs);
7
+ let response = await fetchFn(...fetchArgs);
8
+ if (typeof middlewares.onResponse === "function") {
9
+ const modifiedResponse = await middlewares.onResponse(response);
10
+ if (!(modifiedResponse instanceof Response)) throw new Error("The options.onResponse must return a Response instance!");
11
+ response = modifiedResponse;
12
+ }
13
+ if (!response.ok) throw new Error(`Fetch failed with status ${response.status}`);
14
+ if (!response.body) throw new Error("The response body is empty.");
15
+ return response;
16
+ };
17
+ //#endregion
18
+ export { XFetch as default };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@antdv-next/x-sdk",
3
- "version": "0.0.1",
3
+ "version": "0.0.2",
4
4
  "files": [
5
5
  "dist"
6
6
  ],