@vacbo/opencode-anthropic-fix 0.1.7 → 0.1.9

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 (107) hide show
  1. package/README.md +88 -88
  2. package/dist/opencode-anthropic-auth-cli.mjs +804 -507
  3. package/dist/opencode-anthropic-auth-plugin.js +4751 -4109
  4. package/package.json +67 -59
  5. package/src/__tests__/billing-edge-cases.test.ts +59 -59
  6. package/src/__tests__/bun-proxy.parallel.test.ts +388 -382
  7. package/src/__tests__/cc-comparison.test.ts +87 -87
  8. package/src/__tests__/cc-credentials.test.ts +254 -250
  9. package/src/__tests__/cch-drift-checker.test.ts +51 -51
  10. package/src/__tests__/cch-native-style.test.ts +56 -56
  11. package/src/__tests__/debug-gating.test.ts +42 -42
  12. package/src/__tests__/decomposition-smoke.test.ts +68 -68
  13. package/src/__tests__/fingerprint-regression.test.ts +575 -566
  14. package/src/__tests__/helpers/conversation-history.smoke.test.ts +271 -271
  15. package/src/__tests__/helpers/conversation-history.ts +119 -119
  16. package/src/__tests__/helpers/deferred.smoke.test.ts +103 -103
  17. package/src/__tests__/helpers/deferred.ts +69 -69
  18. package/src/__tests__/helpers/in-memory-storage.smoke.test.ts +155 -155
  19. package/src/__tests__/helpers/in-memory-storage.ts +88 -88
  20. package/src/__tests__/helpers/mock-bun-proxy.smoke.test.ts +68 -68
  21. package/src/__tests__/helpers/mock-bun-proxy.ts +189 -189
  22. package/src/__tests__/helpers/plugin-fetch-harness.smoke.test.ts +273 -273
  23. package/src/__tests__/helpers/plugin-fetch-harness.ts +288 -288
  24. package/src/__tests__/helpers/sse.smoke.test.ts +236 -236
  25. package/src/__tests__/helpers/sse.ts +209 -209
  26. package/src/__tests__/index.parallel.test.ts +605 -595
  27. package/src/__tests__/sanitization-regex.test.ts +112 -112
  28. package/src/__tests__/state-bounds.test.ts +90 -90
  29. package/src/account-identity.test.ts +197 -192
  30. package/src/account-identity.ts +69 -67
  31. package/src/account-state.test.ts +86 -86
  32. package/src/account-state.ts +25 -25
  33. package/src/accounts/matching.test.ts +335 -0
  34. package/src/accounts/matching.ts +167 -0
  35. package/src/accounts/persistence.test.ts +345 -0
  36. package/src/accounts/persistence.ts +432 -0
  37. package/src/accounts/repair.test.ts +276 -0
  38. package/src/accounts/repair.ts +407 -0
  39. package/src/accounts.dedup.test.ts +621 -621
  40. package/src/accounts.test.ts +933 -929
  41. package/src/accounts.ts +633 -989
  42. package/src/backoff.test.ts +345 -345
  43. package/src/backoff.ts +219 -219
  44. package/src/betas.ts +124 -124
  45. package/src/bun-fetch.test.ts +345 -342
  46. package/src/bun-fetch.ts +424 -424
  47. package/src/bun-proxy.test.ts +25 -25
  48. package/src/bun-proxy.ts +209 -209
  49. package/src/cc-credentials.ts +111 -111
  50. package/src/circuit-breaker.test.ts +184 -184
  51. package/src/circuit-breaker.ts +169 -169
  52. package/src/cli/commands/auth.ts +963 -0
  53. package/src/cli/commands/config.ts +547 -0
  54. package/src/cli/formatting.test.ts +406 -0
  55. package/src/cli/formatting.ts +219 -0
  56. package/src/cli.ts +255 -2022
  57. package/src/commands/handlers/betas.ts +100 -0
  58. package/src/commands/handlers/config.ts +99 -0
  59. package/src/commands/handlers/files.ts +375 -0
  60. package/src/commands/oauth-flow.ts +181 -166
  61. package/src/commands/prompts.ts +61 -61
  62. package/src/commands/router.test.ts +421 -0
  63. package/src/commands/router.ts +143 -635
  64. package/src/config.test.ts +482 -482
  65. package/src/config.ts +412 -404
  66. package/src/constants.ts +48 -48
  67. package/src/drift/cch-constants.ts +95 -95
  68. package/src/env.ts +111 -105
  69. package/src/headers/billing.ts +33 -33
  70. package/src/headers/builder.ts +130 -130
  71. package/src/headers/cch.ts +75 -75
  72. package/src/headers/stainless.ts +25 -25
  73. package/src/headers/user-agent.ts +23 -23
  74. package/src/index.ts +436 -828
  75. package/src/models.ts +27 -27
  76. package/src/oauth.test.ts +102 -102
  77. package/src/oauth.ts +178 -178
  78. package/src/parent-pid-watcher.test.ts +148 -148
  79. package/src/parent-pid-watcher.ts +69 -69
  80. package/src/plugin-helpers.ts +82 -82
  81. package/src/refresh-helpers.ts +145 -139
  82. package/src/refresh-lock.test.ts +94 -94
  83. package/src/refresh-lock.ts +93 -93
  84. package/src/request/body.history.test.ts +579 -571
  85. package/src/request/body.ts +255 -255
  86. package/src/request/metadata.ts +65 -65
  87. package/src/request/retry.test.ts +156 -156
  88. package/src/request/retry.ts +67 -67
  89. package/src/request/url.ts +21 -21
  90. package/src/request-orchestration-helpers.ts +648 -0
  91. package/src/response/index.ts +5 -5
  92. package/src/response/mcp.ts +58 -58
  93. package/src/response/streaming.test.ts +313 -311
  94. package/src/response/streaming.ts +412 -410
  95. package/src/rotation.test.ts +304 -301
  96. package/src/rotation.ts +205 -205
  97. package/src/storage.test.ts +547 -547
  98. package/src/storage.ts +315 -291
  99. package/src/system-prompt/builder.ts +38 -38
  100. package/src/system-prompt/index.ts +5 -5
  101. package/src/system-prompt/normalize.ts +60 -60
  102. package/src/system-prompt/sanitize.ts +30 -30
  103. package/src/thinking.ts +21 -20
  104. package/src/token-refresh.test.ts +265 -265
  105. package/src/token-refresh.ts +219 -214
  106. package/src/types.ts +30 -30
  107. package/dist/bun-proxy.mjs +0 -291
@@ -31,82 +31,82 @@ import { randomUUID } from "node:crypto";
31
31
  export type MessageRole = "user" | "assistant";
32
32
 
33
33
  export interface TextBlock {
34
- type: "text";
35
- text: string;
34
+ type: "text";
35
+ text: string;
36
36
  }
37
37
 
38
38
  export interface ToolUseBlock {
39
- type: "tool_use";
40
- id: string;
41
- name: string;
42
- input: Record<string, unknown>;
39
+ type: "tool_use";
40
+ id: string;
41
+ name: string;
42
+ input: Record<string, unknown>;
43
43
  }
44
44
 
45
45
  export interface ToolResultBlock {
46
- type: "tool_result";
47
- tool_use_id: string;
48
- content: string | Array<TextBlock | ImageBlock>;
49
- is_error?: boolean;
46
+ type: "tool_result";
47
+ tool_use_id: string;
48
+ content: string | Array<TextBlock | ImageBlock>;
49
+ is_error?: boolean;
50
50
  }
51
51
 
52
52
  export interface ImageBlock {
53
- type: "image";
54
- source: {
55
- type: "base64";
56
- media_type: string;
57
- data: string;
58
- };
53
+ type: "image";
54
+ source: {
55
+ type: "base64";
56
+ media_type: string;
57
+ data: string;
58
+ };
59
59
  }
60
60
 
61
61
  export type MessageContent = string | Array<TextBlock | ToolUseBlock | ToolResultBlock | ImageBlock>;
62
62
 
63
63
  export interface Message {
64
- role: MessageRole;
65
- content: MessageContent;
64
+ role: MessageRole;
65
+ content: MessageContent;
66
66
  }
67
67
 
68
68
  export interface Conversation {
69
- messages: Message[];
70
- metadata?: Record<string, unknown>;
69
+ messages: Message[];
70
+ metadata?: Record<string, unknown>;
71
71
  }
72
72
 
73
73
  export interface ConversationFactory {
74
- /** Generate unique IDs (default: true) */
75
- generateIds?: boolean;
76
- /** Default prefix for generated IDs */
77
- idPrefix?: string;
74
+ /** Generate unique IDs (default: true) */
75
+ generateIds?: boolean;
76
+ /** Default prefix for generated IDs */
77
+ idPrefix?: string;
78
78
  }
79
79
 
80
80
  export interface MakeConversationOptions extends ConversationFactory {
81
- /** Pre-populated messages array */
82
- messages?: Message[];
83
- /** Optional conversation metadata */
84
- metadata?: Record<string, unknown>;
81
+ /** Pre-populated messages array */
82
+ messages?: Message[];
83
+ /** Optional conversation metadata */
84
+ metadata?: Record<string, unknown>;
85
85
  }
86
86
 
87
87
  export interface MakeMessageOptions {
88
- /** Message role (user or assistant) */
89
- role?: MessageRole;
90
- /** Message content - string or content blocks array */
91
- content?: MessageContent;
88
+ /** Message role (user or assistant) */
89
+ role?: MessageRole;
90
+ /** Message content - string or content blocks array */
91
+ content?: MessageContent;
92
92
  }
93
93
 
94
94
  export interface MakeToolUseOptions {
95
- /** Unique tool use ID (auto-generated if not provided) */
96
- id?: string;
97
- /** Tool name */
98
- name?: string;
99
- /** Tool input parameters */
100
- input?: Record<string, unknown>;
95
+ /** Unique tool use ID (auto-generated if not provided) */
96
+ id?: string;
97
+ /** Tool name */
98
+ name?: string;
99
+ /** Tool input parameters */
100
+ input?: Record<string, unknown>;
101
101
  }
102
102
 
103
103
  export interface MakeToolResultOptions {
104
- /** ID of the tool_use this result corresponds to */
105
- toolUseId?: string;
106
- /** Result content - string or content blocks */
107
- content?: string | Array<TextBlock | ImageBlock>;
108
- /** Whether this result represents an error */
109
- isError?: boolean;
104
+ /** ID of the tool_use this result corresponds to */
105
+ toolUseId?: string;
106
+ /** Result content - string or content blocks */
107
+ content?: string | Array<TextBlock | ImageBlock>;
108
+ /** Whether this result represents an error */
109
+ isError?: boolean;
110
110
  }
111
111
 
112
112
  // ---------------------------------------------------------------------------
@@ -122,14 +122,14 @@ let idCounter = 0;
122
122
  * @returns Unique ID string
123
123
  */
124
124
  export function generateToolUseId(prefix = "tu"): string {
125
- return `${prefix}_${randomUUID().replace(/-/g, "").slice(0, 12)}_${++idCounter}`;
125
+ return `${prefix}_${randomUUID().replace(/-/g, "").slice(0, 12)}_${++idCounter}`;
126
126
  }
127
127
 
128
128
  /**
129
129
  * Reset the ID counter for deterministic tests.
130
130
  */
131
131
  export function resetIdCounter(): void {
132
- idCounter = 0;
132
+ idCounter = 0;
133
133
  }
134
134
 
135
135
  // ---------------------------------------------------------------------------
@@ -151,10 +151,10 @@ export function resetIdCounter(): void {
151
151
  * ```
152
152
  */
153
153
  export function makeConversation(opts: MakeConversationOptions = {}): Conversation {
154
- return {
155
- messages: opts.messages ?? [],
156
- metadata: opts.metadata,
157
- };
154
+ return {
155
+ messages: opts.messages ?? [],
156
+ metadata: opts.metadata,
157
+ };
158
158
  }
159
159
 
160
160
  /**
@@ -173,10 +173,10 @@ export function makeConversation(opts: MakeConversationOptions = {}): Conversati
173
173
  * ```
174
174
  */
175
175
  export function makeMessage(opts: MakeMessageOptions = {}): Message {
176
- const role = opts.role ?? "user";
177
- const content = opts.content ?? "";
176
+ const role = opts.role ?? "user";
177
+ const content = opts.content ?? "";
178
178
 
179
- return { role, content };
179
+ return { role, content };
180
180
  }
181
181
 
182
182
  /**
@@ -186,7 +186,7 @@ export function makeMessage(opts: MakeMessageOptions = {}): Message {
186
186
  * @returns TextBlock object
187
187
  */
188
188
  export function makeTextBlock(text: string): TextBlock {
189
- return { type: "text", text };
189
+ return { type: "text", text };
190
190
  }
191
191
 
192
192
  /**
@@ -204,12 +204,12 @@ export function makeTextBlock(text: string): TextBlock {
204
204
  * ```
205
205
  */
206
206
  export function makeToolUse(opts: MakeToolUseOptions = {}): ToolUseBlock {
207
- return {
208
- type: "tool_use",
209
- id: opts.id ?? generateToolUseId(),
210
- name: opts.name ?? "unnamed_tool",
211
- input: opts.input ?? {},
212
- };
207
+ return {
208
+ type: "tool_use",
209
+ id: opts.id ?? generateToolUseId(),
210
+ name: opts.name ?? "unnamed_tool",
211
+ input: opts.input ?? {},
212
+ };
213
213
  }
214
214
 
215
215
  /**
@@ -227,12 +227,12 @@ export function makeToolUse(opts: MakeToolUseOptions = {}): ToolUseBlock {
227
227
  * ```
228
228
  */
229
229
  export function makeToolResult(opts: MakeToolResultOptions = {}): ToolResultBlock {
230
- return {
231
- type: "tool_result",
232
- tool_use_id: opts.toolUseId ?? generateToolUseId("tr"),
233
- content: opts.content ?? "",
234
- is_error: opts.isError ?? false,
235
- };
230
+ return {
231
+ type: "tool_result",
232
+ tool_use_id: opts.toolUseId ?? generateToolUseId("tr"),
233
+ content: opts.content ?? "",
234
+ is_error: opts.isError ?? false,
235
+ };
236
236
  }
237
237
 
238
238
  // ---------------------------------------------------------------------------
@@ -247,7 +247,7 @@ export function makeToolResult(opts: MakeToolResultOptions = {}): ToolResultBloc
247
247
  * @returns True if the pair is valid
248
248
  */
249
249
  export function validateToolPair(toolUse: ToolUseBlock, toolResult: ToolResultBlock): boolean {
250
- return toolUse.id === toolResult.tool_use_id;
250
+ return toolUse.id === toolResult.tool_use_id;
251
251
  }
252
252
 
253
253
  /**
@@ -258,16 +258,16 @@ export function validateToolPair(toolUse: ToolUseBlock, toolResult: ToolResultBl
258
258
  * @returns The matching ToolResultBlock or undefined
259
259
  */
260
260
  export function findToolResult(messages: Message[], toolUseId: string): ToolResultBlock | undefined {
261
- for (const message of messages) {
262
- if (typeof message.content === "string") continue;
263
-
264
- for (const block of message.content) {
265
- if (block.type === "tool_result" && block.tool_use_id === toolUseId) {
266
- return block;
267
- }
261
+ for (const message of messages) {
262
+ if (typeof message.content === "string") continue;
263
+
264
+ for (const block of message.content) {
265
+ if (block.type === "tool_result" && block.tool_use_id === toolUseId) {
266
+ return block;
267
+ }
268
+ }
268
269
  }
269
- }
270
- return undefined;
270
+ return undefined;
271
271
  }
272
272
 
273
273
  /**
@@ -277,35 +277,35 @@ export function findToolResult(messages: Message[], toolUseId: string): ToolResu
277
277
  * @returns Object with validation results
278
278
  */
279
279
  export function validateConversationTools(conversation: Conversation): {
280
- valid: boolean;
281
- unmatchedToolUses: ToolUseBlock[];
282
- unmatchedToolResults: ToolResultBlock[];
280
+ valid: boolean;
281
+ unmatchedToolUses: ToolUseBlock[];
282
+ unmatchedToolResults: ToolResultBlock[];
283
283
  } {
284
- const toolUses: ToolUseBlock[] = [];
285
- const toolResults: ToolResultBlock[] = [];
286
-
287
- // Collect all tool_use and tool_result blocks
288
- for (const message of conversation.messages) {
289
- if (typeof message.content === "string") continue;
290
-
291
- for (const block of message.content) {
292
- if (block.type === "tool_use") {
293
- toolUses.push(block);
294
- } else if (block.type === "tool_result") {
295
- toolResults.push(block);
296
- }
284
+ const toolUses: ToolUseBlock[] = [];
285
+ const toolResults: ToolResultBlock[] = [];
286
+
287
+ // Collect all tool_use and tool_result blocks
288
+ for (const message of conversation.messages) {
289
+ if (typeof message.content === "string") continue;
290
+
291
+ for (const block of message.content) {
292
+ if (block.type === "tool_use") {
293
+ toolUses.push(block);
294
+ } else if (block.type === "tool_result") {
295
+ toolResults.push(block);
296
+ }
297
+ }
297
298
  }
298
- }
299
299
 
300
- const unmatchedToolUses = toolUses.filter((tu) => !toolResults.some((tr) => tr.tool_use_id === tu.id));
300
+ const unmatchedToolUses = toolUses.filter((tu) => !toolResults.some((tr) => tr.tool_use_id === tu.id));
301
301
 
302
- const unmatchedToolResults = toolResults.filter((tr) => !toolUses.some((tu) => tu.id === tr.tool_use_id));
302
+ const unmatchedToolResults = toolResults.filter((tr) => !toolUses.some((tu) => tu.id === tr.tool_use_id));
303
303
 
304
- return {
305
- valid: unmatchedToolUses.length === 0 && unmatchedToolResults.length === 0,
306
- unmatchedToolUses,
307
- unmatchedToolResults,
308
- };
304
+ return {
305
+ valid: unmatchedToolUses.length === 0 && unmatchedToolResults.length === 0,
306
+ unmatchedToolUses,
307
+ unmatchedToolResults,
308
+ };
309
309
  }
310
310
 
311
311
  // ---------------------------------------------------------------------------
@@ -330,13 +330,13 @@ export function validateConversationTools(conversation: Conversation): {
330
330
  * ```
331
331
  */
332
332
  export function makeToolExchange(
333
- toolName: string,
334
- toolInput: Record<string, unknown>,
335
- resultContent: string,
333
+ toolName: string,
334
+ toolInput: Record<string, unknown>,
335
+ resultContent: string,
336
336
  ): [ToolUseBlock, ToolResultBlock] {
337
- const toolUse = makeToolUse({ name: toolName, input: toolInput });
338
- const toolResult = makeToolResult({ toolUseId: toolUse.id, content: resultContent });
339
- return [toolUse, toolResult];
337
+ const toolUse = makeToolUse({ name: toolName, input: toolInput });
338
+ const toolResult = makeToolResult({ toolUseId: toolUse.id, content: resultContent });
339
+ return [toolUse, toolResult];
340
340
  }
341
341
 
342
342
  /**
@@ -359,18 +359,18 @@ export function makeToolExchange(
359
359
  * ```
360
360
  */
361
361
  export function makeToolConversation(
362
- userPrompt: string,
363
- toolName: string,
364
- toolInput: Record<string, unknown>,
365
- toolOutput: string,
362
+ userPrompt: string,
363
+ toolName: string,
364
+ toolInput: Record<string, unknown>,
365
+ toolOutput: string,
366
366
  ): Conversation {
367
- const [toolUse, toolResult] = makeToolExchange(toolName, toolInput, toolOutput);
368
-
369
- return makeConversation({
370
- messages: [
371
- makeMessage({ role: "user", content: userPrompt }),
372
- makeMessage({ role: "assistant", content: [toolUse] }),
373
- makeMessage({ role: "user", content: [toolResult] }),
374
- ],
375
- });
367
+ const [toolUse, toolResult] = makeToolExchange(toolName, toolInput, toolOutput);
368
+
369
+ return makeConversation({
370
+ messages: [
371
+ makeMessage({ role: "user", content: userPrompt }),
372
+ makeMessage({ role: "assistant", content: [toolUse] }),
373
+ makeMessage({ role: "user", content: [toolResult] }),
374
+ ],
375
+ });
376
376
  }
@@ -2,160 +2,160 @@ import { describe, it, expect } from "vitest";
2
2
  import { createDeferred, createDeferredQueue, nextTick } from "./deferred";
3
3
 
4
4
  describe("deferred helpers", () => {
5
- describe("createDeferred", () => {
6
- it("should resolve with expected value", async () => {
7
- const deferred = createDeferred<string>();
5
+ describe("createDeferred", () => {
6
+ it("should resolve with expected value", async () => {
7
+ const deferred = createDeferred<string>();
8
8
 
9
- deferred.resolve("expected-value");
9
+ deferred.resolve("expected-value");
10
10
 
11
- const result = await deferred.promise;
12
- expect(result).toBe("expected-value");
13
- });
11
+ const result = await deferred.promise;
12
+ expect(result).toBe("expected-value");
13
+ });
14
14
 
15
- it("should reject with expected reason", async () => {
16
- const deferred = createDeferred<string>();
17
- const error = new Error("test-error");
15
+ it("should reject with expected reason", async () => {
16
+ const deferred = createDeferred<string>();
17
+ const error = new Error("test-error");
18
18
 
19
- deferred.reject(error);
19
+ deferred.reject(error);
20
20
 
21
- await expect(deferred.promise).rejects.toBe(error);
22
- });
21
+ await expect(deferred.promise).rejects.toBe(error);
22
+ });
23
23
 
24
- it("should track settled state", async () => {
25
- const deferred = createDeferred<string>();
24
+ it("should track settled state", async () => {
25
+ const deferred = createDeferred<string>();
26
26
 
27
- expect(deferred.settled).toBe(false);
27
+ expect(deferred.settled).toBe(false);
28
28
 
29
- deferred.resolve("done");
29
+ deferred.resolve("done");
30
30
 
31
- expect(deferred.settled).toBe(true);
32
- await deferred.promise;
33
- });
31
+ expect(deferred.settled).toBe(true);
32
+ await deferred.promise;
33
+ });
34
34
 
35
- it("should ignore second resolve", async () => {
36
- const deferred = createDeferred<string>();
35
+ it("should ignore second resolve", async () => {
36
+ const deferred = createDeferred<string>();
37
37
 
38
- deferred.resolve("first");
39
- deferred.resolve("second");
38
+ deferred.resolve("first");
39
+ deferred.resolve("second");
40
40
 
41
- const result = await deferred.promise;
42
- expect(result).toBe("first");
43
- });
41
+ const result = await deferred.promise;
42
+ expect(result).toBe("first");
43
+ });
44
44
 
45
- it("should ignore reject after resolve", async () => {
46
- const deferred = createDeferred<string>();
45
+ it("should ignore reject after resolve", async () => {
46
+ const deferred = createDeferred<string>();
47
47
 
48
- deferred.resolve("value");
49
- deferred.reject(new Error("ignored"));
48
+ deferred.resolve("value");
49
+ deferred.reject(new Error("ignored"));
50
50
 
51
- const result = await deferred.promise;
52
- expect(result).toBe("value");
51
+ const result = await deferred.promise;
52
+ expect(result).toBe("value");
53
+ });
53
54
  });
54
- });
55
55
 
56
- describe("createDeferredQueue", () => {
57
- it("should resolve deferreds in FIFO order", async () => {
58
- const queue = createDeferredQueue<string>();
56
+ describe("createDeferredQueue", () => {
57
+ it("should resolve deferreds in FIFO order", async () => {
58
+ const queue = createDeferredQueue<string>();
59
59
 
60
- const d1 = queue.enqueue();
61
- const d2 = queue.enqueue();
62
- const d3 = queue.enqueue();
60
+ const d1 = queue.enqueue();
61
+ const d2 = queue.enqueue();
62
+ const d3 = queue.enqueue();
63
63
 
64
- expect(queue.pending).toBe(3);
64
+ expect(queue.pending).toBe(3);
65
65
 
66
- queue.resolveNext("first");
67
- queue.resolveNext("second");
68
- queue.resolveNext("third");
66
+ queue.resolveNext("first");
67
+ queue.resolveNext("second");
68
+ queue.resolveNext("third");
69
69
 
70
- expect(queue.pending).toBe(0);
70
+ expect(queue.pending).toBe(0);
71
71
 
72
- const results = await Promise.all([d1.promise, d2.promise, d3.promise]);
72
+ const results = await Promise.all([d1.promise, d2.promise, d3.promise]);
73
73
 
74
- expect(results).toEqual(["first", "second", "third"]);
75
- });
74
+ expect(results).toEqual(["first", "second", "third"]);
75
+ });
76
76
 
77
- it("should reject deferreds in FIFO order", async () => {
78
- const queue = createDeferredQueue<string>();
77
+ it("should reject deferreds in FIFO order", async () => {
78
+ const queue = createDeferredQueue<string>();
79
79
 
80
- const d1 = queue.enqueue();
81
- const d2 = queue.enqueue();
80
+ const d1 = queue.enqueue();
81
+ const d2 = queue.enqueue();
82
82
 
83
- const error1 = new Error("error-1");
84
- const error2 = new Error("error-2");
83
+ const error1 = new Error("error-1");
84
+ const error2 = new Error("error-2");
85
85
 
86
- queue.rejectNext(error1);
87
- queue.rejectNext(error2);
86
+ queue.rejectNext(error1);
87
+ queue.rejectNext(error2);
88
88
 
89
- await expect(d1.promise).rejects.toBe(error1);
90
- await expect(d2.promise).rejects.toBe(error2);
91
- });
89
+ await expect(d1.promise).rejects.toBe(error1);
90
+ await expect(d2.promise).rejects.toBe(error2);
91
+ });
92
92
 
93
- it("should return false when resolving empty queue", () => {
94
- const queue = createDeferredQueue<string>();
93
+ it("should return false when resolving empty queue", () => {
94
+ const queue = createDeferredQueue<string>();
95
95
 
96
- const result = queue.resolveNext("value");
96
+ const result = queue.resolveNext("value");
97
97
 
98
- expect(result).toBe(false);
99
- });
98
+ expect(result).toBe(false);
99
+ });
100
100
 
101
- it("should return false when rejecting empty queue", () => {
102
- const queue = createDeferredQueue<string>();
101
+ it("should return false when rejecting empty queue", () => {
102
+ const queue = createDeferredQueue<string>();
103
103
 
104
- const result = queue.rejectNext(new Error("test"));
104
+ const result = queue.rejectNext(new Error("test"));
105
105
 
106
- expect(result).toBe(false);
107
- });
106
+ expect(result).toBe(false);
107
+ });
108
108
 
109
- it("should handle mixed resolve and reject", async () => {
110
- const queue = createDeferredQueue<string>();
109
+ it("should handle mixed resolve and reject", async () => {
110
+ const queue = createDeferredQueue<string>();
111
111
 
112
- const d1 = queue.enqueue();
113
- const d2 = queue.enqueue();
114
- const d3 = queue.enqueue();
112
+ const d1 = queue.enqueue();
113
+ const d2 = queue.enqueue();
114
+ const d3 = queue.enqueue();
115
115
 
116
- queue.resolveNext("success");
117
- queue.rejectNext(new Error("failure"));
118
- queue.resolveNext("another-success");
116
+ queue.resolveNext("success");
117
+ queue.rejectNext(new Error("failure"));
118
+ queue.resolveNext("another-success");
119
119
 
120
- const r1 = await d1.promise;
121
- expect(r1).toBe("success");
120
+ const r1 = await d1.promise;
121
+ expect(r1).toBe("success");
122
122
 
123
- await expect(d2.promise).rejects.toThrow("failure");
123
+ await expect(d2.promise).rejects.toThrow("failure");
124
124
 
125
- const r3 = await d3.promise;
126
- expect(r3).toBe("another-success");
125
+ const r3 = await d3.promise;
126
+ expect(r3).toBe("another-success");
127
+ });
127
128
  });
128
- });
129
129
 
130
- describe("nextTick", () => {
131
- it("should allow pending promises to settle", async () => {
132
- const deferred = createDeferred<string>();
133
- let resolved = false;
130
+ describe("nextTick", () => {
131
+ it("should allow pending promises to settle", async () => {
132
+ const deferred = createDeferred<string>();
133
+ let resolved = false;
134
134
 
135
- deferred.promise.then(() => {
136
- resolved = true;
137
- });
135
+ deferred.promise.then(() => {
136
+ resolved = true;
137
+ });
138
138
 
139
- deferred.resolve("done");
139
+ deferred.resolve("done");
140
140
 
141
- expect(resolved).toBe(false);
141
+ expect(resolved).toBe(false);
142
142
 
143
- await nextTick();
143
+ await nextTick();
144
144
 
145
- expect(resolved).toBe(true);
146
- });
145
+ expect(resolved).toBe(true);
146
+ });
147
147
 
148
- it("should resolve after microtask queue", async () => {
149
- const order: string[] = [];
148
+ it("should resolve after microtask queue", async () => {
149
+ const order: string[] = [];
150
150
 
151
- Promise.resolve().then(() => order.push("promise-1"));
152
- Promise.resolve().then(() => order.push("promise-2"));
151
+ Promise.resolve().then(() => order.push("promise-1"));
152
+ Promise.resolve().then(() => order.push("promise-2"));
153
153
 
154
- await nextTick();
154
+ await nextTick();
155
155
 
156
- order.push("after-nextTick");
156
+ order.push("after-nextTick");
157
157
 
158
- expect(order).toEqual(["promise-1", "promise-2", "after-nextTick"]);
158
+ expect(order).toEqual(["promise-1", "promise-2", "after-nextTick"]);
159
+ });
159
160
  });
160
- });
161
161
  });