vovk 3.0.0-draft.272 → 3.0.0-draft.273
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/cjs/JSONLinesResponse.d.ts +5 -0
- package/cjs/JSONLinesResponse.js +40 -6
- package/cjs/VovkApp.js +1 -0
- package/mjs/JSONLinesResponse.d.ts +5 -0
- package/mjs/JSONLinesResponse.js +40 -6
- package/mjs/VovkApp.js +1 -0
- package/package.json +1 -1
|
@@ -6,10 +6,15 @@ export declare class JSONLinesResponse<T> extends Response {
|
|
|
6
6
|
controller?: ReadableStreamDefaultController;
|
|
7
7
|
readonly encoder: TextEncoder;
|
|
8
8
|
readonly readableStream: ReadableStream;
|
|
9
|
+
private iteratorQueue;
|
|
10
|
+
private iteratorResolvers;
|
|
9
11
|
constructor(requestHeaders: Awaited<ReturnType<typeof headers>>, init?: ResponseInit);
|
|
10
12
|
send: (data: T | StreamAbortMessage) => void;
|
|
11
13
|
close: () => void;
|
|
12
14
|
throw: (e: KnownAny) => void;
|
|
13
15
|
[Symbol.dispose]: () => void;
|
|
14
16
|
[Symbol.asyncDispose]: () => void;
|
|
17
|
+
[Symbol.asyncIterator]: () => {
|
|
18
|
+
next: () => Promise<IteratorResult<T | StreamAbortMessage>>;
|
|
19
|
+
};
|
|
15
20
|
}
|
package/cjs/JSONLinesResponse.js
CHANGED
|
@@ -7,6 +7,9 @@ class JSONLinesResponse extends Response {
|
|
|
7
7
|
controller;
|
|
8
8
|
encoder;
|
|
9
9
|
readableStream;
|
|
10
|
+
// Add these private fields for async iteration
|
|
11
|
+
iteratorQueue = [];
|
|
12
|
+
iteratorResolvers = [];
|
|
10
13
|
constructor(requestHeaders, init) {
|
|
11
14
|
const encoder = new TextEncoder();
|
|
12
15
|
let readableController;
|
|
@@ -39,7 +42,18 @@ class JSONLinesResponse extends Response {
|
|
|
39
42
|
const { controller, encoder } = this;
|
|
40
43
|
if (this.isClosed)
|
|
41
44
|
return;
|
|
42
|
-
|
|
45
|
+
// Enqueue to the ReadableStream
|
|
46
|
+
controller?.enqueue(encoder.encode(JSON.stringify(data) + '\n'));
|
|
47
|
+
// Handle async iterator consumers
|
|
48
|
+
if (this.iteratorResolvers.length > 0) {
|
|
49
|
+
// If there's a pending next() call, resolve it immediately
|
|
50
|
+
const resolve = this.iteratorResolvers.shift();
|
|
51
|
+
resolve({ value: data, done: false });
|
|
52
|
+
}
|
|
53
|
+
else {
|
|
54
|
+
// Otherwise, queue the value for later consumption
|
|
55
|
+
this.iteratorQueue.push(data);
|
|
56
|
+
}
|
|
43
57
|
};
|
|
44
58
|
close = () => {
|
|
45
59
|
const { controller } = this;
|
|
@@ -47,16 +61,36 @@ class JSONLinesResponse extends Response {
|
|
|
47
61
|
return;
|
|
48
62
|
this.isClosed = true;
|
|
49
63
|
controller?.close();
|
|
64
|
+
// Resolve all pending iterator next() calls with done: true
|
|
65
|
+
while (this.iteratorResolvers.length > 0) {
|
|
66
|
+
const resolve = this.iteratorResolvers.shift();
|
|
67
|
+
resolve({ done: true, value: undefined });
|
|
68
|
+
}
|
|
50
69
|
};
|
|
51
70
|
throw = (e) => {
|
|
52
71
|
this.send({ isError: true, reason: e instanceof Error ? e.message : e });
|
|
53
72
|
return this.close();
|
|
54
73
|
};
|
|
55
|
-
[Symbol.dispose] = () =>
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
74
|
+
[Symbol.dispose] = () => this.close();
|
|
75
|
+
[Symbol.asyncDispose] = () => this.close();
|
|
76
|
+
[Symbol.asyncIterator] = () => {
|
|
77
|
+
return {
|
|
78
|
+
next: async () => {
|
|
79
|
+
// If we have queued values, return them immediately
|
|
80
|
+
if (this.iteratorQueue.length > 0) {
|
|
81
|
+
const value = this.iteratorQueue.shift();
|
|
82
|
+
return { value, done: false };
|
|
83
|
+
}
|
|
84
|
+
// If the stream is closed and no more values, we're done
|
|
85
|
+
if (this.isClosed) {
|
|
86
|
+
return { done: true, value: undefined };
|
|
87
|
+
}
|
|
88
|
+
// Otherwise, wait for the next value or close
|
|
89
|
+
return new Promise((resolve) => {
|
|
90
|
+
this.iteratorResolvers.push(resolve);
|
|
91
|
+
});
|
|
92
|
+
},
|
|
93
|
+
};
|
|
60
94
|
};
|
|
61
95
|
}
|
|
62
96
|
exports.JSONLinesResponse = JSONLinesResponse;
|
package/cjs/VovkApp.js
CHANGED
|
@@ -152,6 +152,7 @@ class VovkApp {
|
|
|
152
152
|
const result = await staticMethod.call(controller, req, methodParams);
|
|
153
153
|
const isIterator = typeof result === 'object' &&
|
|
154
154
|
!!result &&
|
|
155
|
+
!(result instanceof Response) && // don't invoke asyncIterable for JSONLinesResponse
|
|
155
156
|
((Reflect.has(result, Symbol.iterator) &&
|
|
156
157
|
typeof result[Symbol.iterator] === 'function') ||
|
|
157
158
|
(Reflect.has(result, Symbol.asyncIterator) &&
|
|
@@ -6,10 +6,15 @@ export declare class JSONLinesResponse<T> extends Response {
|
|
|
6
6
|
controller?: ReadableStreamDefaultController;
|
|
7
7
|
readonly encoder: TextEncoder;
|
|
8
8
|
readonly readableStream: ReadableStream;
|
|
9
|
+
private iteratorQueue;
|
|
10
|
+
private iteratorResolvers;
|
|
9
11
|
constructor(requestHeaders: Awaited<ReturnType<typeof headers>>, init?: ResponseInit);
|
|
10
12
|
send: (data: T | StreamAbortMessage) => void;
|
|
11
13
|
close: () => void;
|
|
12
14
|
throw: (e: KnownAny) => void;
|
|
13
15
|
[Symbol.dispose]: () => void;
|
|
14
16
|
[Symbol.asyncDispose]: () => void;
|
|
17
|
+
[Symbol.asyncIterator]: () => {
|
|
18
|
+
next: () => Promise<IteratorResult<T | StreamAbortMessage>>;
|
|
19
|
+
};
|
|
15
20
|
}
|
package/mjs/JSONLinesResponse.js
CHANGED
|
@@ -7,6 +7,9 @@ class JSONLinesResponse extends Response {
|
|
|
7
7
|
controller;
|
|
8
8
|
encoder;
|
|
9
9
|
readableStream;
|
|
10
|
+
// Add these private fields for async iteration
|
|
11
|
+
iteratorQueue = [];
|
|
12
|
+
iteratorResolvers = [];
|
|
10
13
|
constructor(requestHeaders, init) {
|
|
11
14
|
const encoder = new TextEncoder();
|
|
12
15
|
let readableController;
|
|
@@ -39,7 +42,18 @@ class JSONLinesResponse extends Response {
|
|
|
39
42
|
const { controller, encoder } = this;
|
|
40
43
|
if (this.isClosed)
|
|
41
44
|
return;
|
|
42
|
-
|
|
45
|
+
// Enqueue to the ReadableStream
|
|
46
|
+
controller?.enqueue(encoder.encode(JSON.stringify(data) + '\n'));
|
|
47
|
+
// Handle async iterator consumers
|
|
48
|
+
if (this.iteratorResolvers.length > 0) {
|
|
49
|
+
// If there's a pending next() call, resolve it immediately
|
|
50
|
+
const resolve = this.iteratorResolvers.shift();
|
|
51
|
+
resolve({ value: data, done: false });
|
|
52
|
+
}
|
|
53
|
+
else {
|
|
54
|
+
// Otherwise, queue the value for later consumption
|
|
55
|
+
this.iteratorQueue.push(data);
|
|
56
|
+
}
|
|
43
57
|
};
|
|
44
58
|
close = () => {
|
|
45
59
|
const { controller } = this;
|
|
@@ -47,16 +61,36 @@ class JSONLinesResponse extends Response {
|
|
|
47
61
|
return;
|
|
48
62
|
this.isClosed = true;
|
|
49
63
|
controller?.close();
|
|
64
|
+
// Resolve all pending iterator next() calls with done: true
|
|
65
|
+
while (this.iteratorResolvers.length > 0) {
|
|
66
|
+
const resolve = this.iteratorResolvers.shift();
|
|
67
|
+
resolve({ done: true, value: undefined });
|
|
68
|
+
}
|
|
50
69
|
};
|
|
51
70
|
throw = (e) => {
|
|
52
71
|
this.send({ isError: true, reason: e instanceof Error ? e.message : e });
|
|
53
72
|
return this.close();
|
|
54
73
|
};
|
|
55
|
-
[Symbol.dispose] = () =>
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
74
|
+
[Symbol.dispose] = () => this.close();
|
|
75
|
+
[Symbol.asyncDispose] = () => this.close();
|
|
76
|
+
[Symbol.asyncIterator] = () => {
|
|
77
|
+
return {
|
|
78
|
+
next: async () => {
|
|
79
|
+
// If we have queued values, return them immediately
|
|
80
|
+
if (this.iteratorQueue.length > 0) {
|
|
81
|
+
const value = this.iteratorQueue.shift();
|
|
82
|
+
return { value, done: false };
|
|
83
|
+
}
|
|
84
|
+
// If the stream is closed and no more values, we're done
|
|
85
|
+
if (this.isClosed) {
|
|
86
|
+
return { done: true, value: undefined };
|
|
87
|
+
}
|
|
88
|
+
// Otherwise, wait for the next value or close
|
|
89
|
+
return new Promise((resolve) => {
|
|
90
|
+
this.iteratorResolvers.push(resolve);
|
|
91
|
+
});
|
|
92
|
+
},
|
|
93
|
+
};
|
|
60
94
|
};
|
|
61
95
|
}
|
|
62
96
|
exports.JSONLinesResponse = JSONLinesResponse;
|
package/mjs/VovkApp.js
CHANGED
|
@@ -152,6 +152,7 @@ class VovkApp {
|
|
|
152
152
|
const result = await staticMethod.call(controller, req, methodParams);
|
|
153
153
|
const isIterator = typeof result === 'object' &&
|
|
154
154
|
!!result &&
|
|
155
|
+
!(result instanceof Response) && // don't invoke asyncIterable for JSONLinesResponse
|
|
155
156
|
((Reflect.has(result, Symbol.iterator) &&
|
|
156
157
|
typeof result[Symbol.iterator] === 'function') ||
|
|
157
158
|
(Reflect.has(result, Symbol.asyncIterator) &&
|