fullstacked 0.11.3-1148 → 0.11.3-1150

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.
@@ -1,318 +1,318 @@
1
- import { toByteArray } from "../base64";
2
- import { bridge } from "../bridge";
3
- import {
4
- deserializeArgs,
5
- getLowestKeyIdAvailable,
6
- serializeArgs
7
- } from "../bridge/serialization";
8
- import core_message from "../core_message";
9
-
10
- const te = new TextEncoder();
11
-
12
- type ResponseSimplified = {
13
- statusCode: number;
14
- statusMessage: string;
15
- headers: Record<string, string>;
16
- body: string | Uint8Array | AsyncIterableIterator<string | Uint8Array>;
17
- };
18
-
19
- const activeFetchRequests = new Map<
20
- number,
21
- {
22
- resolve: (response: ResponseSimplified) => void;
23
- reject: (error: string) => void;
24
- }
25
- >();
26
-
27
- let addedListener = false;
28
- function receivedResponse(base64Data: string) {
29
- const data = toByteArray(base64Data);
30
- const args = deserializeArgs(data);
31
-
32
- const id = args.at(0);
33
- const fetchRequest = activeFetchRequests.get(id);
34
-
35
- const [statusCode, statusMessage, headersStr, body] = args.slice(1);
36
-
37
- const response: ResponseSimplified = {
38
- statusCode,
39
- statusMessage,
40
- headers: headersStr ? JSON.parse(headersStr) : {},
41
- body
42
- };
43
-
44
- if (statusCode >= 400) {
45
- fetchRequest.reject(JSON.stringify(response));
46
- } else {
47
- fetchRequest.resolve(response);
48
- }
49
-
50
- activeFetchRequests.delete(id);
51
- }
52
-
53
- // 15
54
- export default function core_fetch(
55
- url: string,
56
- options?: Partial<FetchOptions>
57
- ): Promise<FetchResponse & { body: Uint8Array }>;
58
- export default function core_fetch(
59
- url: string,
60
- options?: Partial<FetchOptions> & { encoding: "utf8" }
61
- ): Promise<FetchResponse & { body: string }>;
62
- export default function core_fetch(
63
- url: string,
64
- options?: Partial<FetchOptions> & { stream?: boolean; encoding?: "utf8" }
65
- ) {
66
- const method = options?.method || "GET";
67
-
68
- const headers = options?.headers ? JSON.stringify(options.headers) : "";
69
-
70
- const body = options?.body
71
- ? typeof options.body === "string"
72
- ? te.encode(options.body)
73
- : options.body
74
- : new Uint8Array();
75
-
76
- const timeout = options?.timeout || 10;
77
-
78
- const requestId = getLowestKeyIdAvailable(activeFetchRequests);
79
-
80
- const payload = new Uint8Array([
81
- 15,
82
-
83
- ...serializeArgs([
84
- requestId,
85
- method,
86
- url,
87
- headers,
88
- body,
89
- timeout,
90
- options?.encoding === "utf8"
91
- ])
92
- ]);
93
-
94
- if (!addedListener) {
95
- core_message.addListener("fetch-response", receivedResponse);
96
- addedListener = true;
97
- }
98
-
99
- return new Promise<ResponseSimplified>((resolve, reject) => {
100
- activeFetchRequests.set(requestId, {
101
- resolve,
102
- reject
103
- });
104
- bridge(payload);
105
- });
106
- }
107
-
108
- const activeFetch2Requests = new Map<
109
- number,
110
- {
111
- url: string;
112
- resolveResponse(response: Response): void;
113
- resolveStream?(param: { done: boolean; chunk: Uint8Array }): void;
114
- }
115
- >();
116
-
117
- let addedListener2 = false;
118
- function receivedResponse2(base64Data: string) {
119
- const data = toByteArray(base64Data);
120
- const args = deserializeArgs(data);
121
-
122
- const id = args.at(0);
123
- const request = activeFetch2Requests.get(id);
124
-
125
- if (request.resolveStream) {
126
- const [done, chunk] = args.slice(1);
127
- request.resolveStream({ done, chunk });
128
- if (done) {
129
- activeFetch2Requests.delete(id);
130
- }
131
- return;
132
- }
133
-
134
- const [status, statusText, headersStr] = args.slice(1);
135
-
136
- const ok = status <= 299;
137
-
138
- let finished = false;
139
- const read = async () => {
140
- if (finished) {
141
- return { done: true };
142
- }
143
-
144
- const { done, chunk } = await new Promise<{
145
- done: boolean;
146
- chunk: Uint8Array;
147
- }>((resolve) => {
148
- request.resolveStream = resolve;
149
- });
150
- finished = done;
151
-
152
- return { done: false, value: chunk };
153
- };
154
-
155
- const it = {
156
- next: read
157
- } as AsyncIterator<Uint8Array>;
158
-
159
- const responseIterator = {
160
- [Symbol.asyncIterator]() {
161
- return it;
162
- }
163
- };
164
-
165
- const readBody = async () => {
166
- if (!ok) {
167
- return te.encode(statusText);
168
- }
169
- let body = new Uint8Array();
170
- for await (const chunk of responseIterator) {
171
- const buffer = new Uint8Array(body.byteLength + chunk.byteLength);
172
- buffer.set(body, 0);
173
- buffer.set(chunk, body.length);
174
- body = buffer;
175
- }
176
- return body;
177
- };
178
-
179
- const response: Response = {
180
- url: request.url,
181
- redirected: false,
182
- type: "default",
183
- bodyUsed: false,
184
- ok,
185
- status,
186
- statusText,
187
- headers: objectToHeaders(JSON.parse(headersStr || "{}")),
188
-
189
- body: iteratorToStream(it),
190
-
191
- bytes: readBody,
192
- arrayBuffer: async () => {
193
- const data = await readBody();
194
- return data.buffer;
195
- },
196
- blob: async () => {
197
- const body = await readBody();
198
- return new Blob([body]);
199
- },
200
- text: async () => {
201
- const body = await readBody();
202
- return new TextDecoder().decode(body);
203
- },
204
- json: async () => {
205
- const body = await readBody();
206
- return JSON.parse(new TextDecoder().decode(body));
207
- },
208
-
209
- // not implemented
210
- clone: () => null,
211
- formData: async () => null
212
- };
213
-
214
- request.resolveResponse(response);
215
- }
216
-
217
- export function core_fetch2(request: Request): Promise<Response>;
218
- export function core_fetch2(
219
- url: string | URL,
220
- options?: RequestInit
221
- ): Promise<Response>;
222
- export async function core_fetch2(
223
- urlOrRequest: string | URL | Request,
224
- options?: RequestInit
225
- ): Promise<Response> {
226
- if (!addedListener2) {
227
- core_message.addListener("fetch2-response", receivedResponse2);
228
- addedListener2 = true;
229
- }
230
-
231
- if (urlOrRequest instanceof Request) {
232
- const bodyReader = urlOrRequest.body?.getReader();
233
- const body = bodyReader ? (await bodyReader.read()).value : "";
234
-
235
- options = {
236
- method: urlOrRequest.method,
237
- headers: urlOrRequest.headers,
238
- signal: urlOrRequest.signal,
239
- body
240
- };
241
-
242
- return fetch2(urlOrRequest.url, options);
243
- }
244
-
245
- const url =
246
- urlOrRequest instanceof URL ? urlOrRequest.toString() : urlOrRequest;
247
-
248
- return fetch2(url, options);
249
- }
250
-
251
- // 16
252
- function fetch2(url: string, options?: RequestInit): Promise<Response> {
253
- const id = getLowestKeyIdAvailable(activeFetch2Requests);
254
-
255
- const headers = options?.headers
256
- ? options.headers instanceof Headers
257
- ? JSON.stringify(headersToObject(options.headers))
258
- : JSON.stringify(options.headers)
259
- : "";
260
- const body = options?.body
261
- ? typeof options.body === "string"
262
- ? te.encode(options.body)
263
- : options.body
264
- : new Uint8Array();
265
-
266
- if (options?.signal) {
267
- options.signal.onabort = () => {
268
- console.log("ABORT REQUEST");
269
- // cancel
270
- };
271
- }
272
-
273
- const payload = new Uint8Array([
274
- 16,
275
-
276
- ...serializeArgs([id, options?.method || "GET", url, headers, body])
277
- ]);
278
-
279
- return new Promise<Response>((resolve) => {
280
- activeFetch2Requests.set(id, {
281
- url,
282
- resolveResponse: resolve
283
- });
284
- bridge(payload);
285
- });
286
- }
287
-
288
- function objectToHeaders(o: Record<string, string>) {
289
- const headers = new Headers();
290
- Object.entries(o).forEach(([n, v]) => {
291
- headers.set(n, v);
292
- });
293
- return headers;
294
- }
295
-
296
- const headersToObject = (h: Headers) => {
297
- const obj = {};
298
- for (const [n, v] of h.entries()) {
299
- obj[n] = v;
300
- }
301
- return obj;
302
- };
303
-
304
- // https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream#convert_an_iterator_or_async_iterator_to_a_stream
305
- function iteratorToStream(iterator: AsyncIterator<Uint8Array>) {
306
- return new ReadableStream({
307
- async pull(controller) {
308
- const { value, done } = await iterator.next();
309
-
310
- if (value) {
311
- controller.enqueue(value);
312
- }
313
- if (done) {
314
- controller.close();
315
- }
316
- }
317
- });
318
- }
1
+ import { toByteArray } from "../base64";
2
+ import { bridge } from "../bridge";
3
+ import {
4
+ deserializeArgs,
5
+ getLowestKeyIdAvailable,
6
+ serializeArgs
7
+ } from "../bridge/serialization";
8
+ import core_message from "../core_message";
9
+
10
+ const te = new TextEncoder();
11
+
12
+ type ResponseSimplified = {
13
+ statusCode: number;
14
+ statusMessage: string;
15
+ headers: Record<string, string>;
16
+ body: string | Uint8Array | AsyncIterableIterator<string | Uint8Array>;
17
+ };
18
+
19
+ const activeFetchRequests = new Map<
20
+ number,
21
+ {
22
+ resolve: (response: ResponseSimplified) => void;
23
+ reject: (error: string) => void;
24
+ }
25
+ >();
26
+
27
+ let addedListener = false;
28
+ function receivedResponse(base64Data: string) {
29
+ const data = toByteArray(base64Data);
30
+ const args = deserializeArgs(data);
31
+
32
+ const id = args.at(0);
33
+ const fetchRequest = activeFetchRequests.get(id);
34
+
35
+ const [statusCode, statusMessage, headersStr, body] = args.slice(1);
36
+
37
+ const response: ResponseSimplified = {
38
+ statusCode,
39
+ statusMessage,
40
+ headers: headersStr ? JSON.parse(headersStr) : {},
41
+ body
42
+ };
43
+
44
+ if (statusCode >= 400) {
45
+ fetchRequest.reject(JSON.stringify(response));
46
+ } else {
47
+ fetchRequest.resolve(response);
48
+ }
49
+
50
+ activeFetchRequests.delete(id);
51
+ }
52
+
53
+ // 15
54
+ export default function core_fetch(
55
+ url: string,
56
+ options?: Partial<FetchOptions>
57
+ ): Promise<FetchResponse & { body: Uint8Array }>;
58
+ export default function core_fetch(
59
+ url: string,
60
+ options?: Partial<FetchOptions> & { encoding: "utf8" }
61
+ ): Promise<FetchResponse & { body: string }>;
62
+ export default function core_fetch(
63
+ url: string,
64
+ options?: Partial<FetchOptions> & { stream?: boolean; encoding?: "utf8" }
65
+ ) {
66
+ const method = options?.method || "GET";
67
+
68
+ const headers = options?.headers ? JSON.stringify(options.headers) : "";
69
+
70
+ const body = options?.body
71
+ ? typeof options.body === "string"
72
+ ? te.encode(options.body)
73
+ : options.body
74
+ : new Uint8Array();
75
+
76
+ const timeout = options?.timeout || 10;
77
+
78
+ const requestId = getLowestKeyIdAvailable(activeFetchRequests);
79
+
80
+ const payload = new Uint8Array([
81
+ 15,
82
+
83
+ ...serializeArgs([
84
+ requestId,
85
+ method,
86
+ url,
87
+ headers,
88
+ body,
89
+ timeout,
90
+ options?.encoding === "utf8"
91
+ ])
92
+ ]);
93
+
94
+ if (!addedListener) {
95
+ core_message.addListener("fetch-response", receivedResponse);
96
+ addedListener = true;
97
+ }
98
+
99
+ return new Promise<ResponseSimplified>((resolve, reject) => {
100
+ activeFetchRequests.set(requestId, {
101
+ resolve,
102
+ reject
103
+ });
104
+ bridge(payload);
105
+ });
106
+ }
107
+
108
+ const activeFetch2Requests = new Map<
109
+ number,
110
+ {
111
+ url: string;
112
+ resolveResponse(response: Response): void;
113
+ resolveStream?(param: { done: boolean; chunk: Uint8Array }): void;
114
+ }
115
+ >();
116
+
117
+ let addedListener2 = false;
118
+ function receivedResponse2(base64Data: string) {
119
+ const data = toByteArray(base64Data);
120
+ const args = deserializeArgs(data);
121
+
122
+ const id = args.at(0);
123
+ const request = activeFetch2Requests.get(id);
124
+
125
+ if (request.resolveStream) {
126
+ const [done, chunk] = args.slice(1);
127
+ request.resolveStream({ done, chunk });
128
+ if (done) {
129
+ activeFetch2Requests.delete(id);
130
+ }
131
+ return;
132
+ }
133
+
134
+ const [status, statusText, headersStr] = args.slice(1);
135
+
136
+ const ok = status <= 299;
137
+
138
+ let finished = false;
139
+ const read = async () => {
140
+ if (finished) {
141
+ return { done: true };
142
+ }
143
+
144
+ const { done, chunk } = await new Promise<{
145
+ done: boolean;
146
+ chunk: Uint8Array;
147
+ }>((resolve) => {
148
+ request.resolveStream = resolve;
149
+ });
150
+ finished = done;
151
+
152
+ return { done: false, value: chunk };
153
+ };
154
+
155
+ const it = {
156
+ next: read
157
+ } as AsyncIterator<Uint8Array>;
158
+
159
+ const responseIterator = {
160
+ [Symbol.asyncIterator]() {
161
+ return it;
162
+ }
163
+ };
164
+
165
+ const readBody = async () => {
166
+ if (!ok) {
167
+ return te.encode(statusText);
168
+ }
169
+ let body = new Uint8Array();
170
+ for await (const chunk of responseIterator) {
171
+ const buffer = new Uint8Array(body.byteLength + chunk.byteLength);
172
+ buffer.set(body, 0);
173
+ buffer.set(chunk, body.length);
174
+ body = buffer;
175
+ }
176
+ return body;
177
+ };
178
+
179
+ const response: Response = {
180
+ url: request.url,
181
+ redirected: false,
182
+ type: "default",
183
+ bodyUsed: false,
184
+ ok,
185
+ status,
186
+ statusText,
187
+ headers: objectToHeaders(JSON.parse(headersStr || "{}")),
188
+
189
+ body: iteratorToStream(it),
190
+
191
+ bytes: readBody,
192
+ arrayBuffer: async () => {
193
+ const data = await readBody();
194
+ return data.buffer;
195
+ },
196
+ blob: async () => {
197
+ const body = await readBody();
198
+ return new Blob([body]);
199
+ },
200
+ text: async () => {
201
+ const body = await readBody();
202
+ return new TextDecoder().decode(body);
203
+ },
204
+ json: async () => {
205
+ const body = await readBody();
206
+ return JSON.parse(new TextDecoder().decode(body));
207
+ },
208
+
209
+ // not implemented
210
+ clone: () => null,
211
+ formData: async () => null
212
+ };
213
+
214
+ request.resolveResponse(response);
215
+ }
216
+
217
+ export function core_fetch2(request: Request): Promise<Response>;
218
+ export function core_fetch2(
219
+ url: string | URL,
220
+ options?: RequestInit
221
+ ): Promise<Response>;
222
+ export async function core_fetch2(
223
+ urlOrRequest: string | URL | Request,
224
+ options?: RequestInit
225
+ ): Promise<Response> {
226
+ if (!addedListener2) {
227
+ core_message.addListener("fetch2-response", receivedResponse2);
228
+ addedListener2 = true;
229
+ }
230
+
231
+ if (urlOrRequest instanceof Request) {
232
+ const bodyReader = urlOrRequest.body?.getReader();
233
+ const body = bodyReader ? (await bodyReader.read()).value : "";
234
+
235
+ options = {
236
+ method: urlOrRequest.method,
237
+ headers: urlOrRequest.headers,
238
+ signal: urlOrRequest.signal,
239
+ body
240
+ };
241
+
242
+ return fetch2(urlOrRequest.url, options);
243
+ }
244
+
245
+ const url =
246
+ urlOrRequest instanceof URL ? urlOrRequest.toString() : urlOrRequest;
247
+
248
+ return fetch2(url, options);
249
+ }
250
+
251
+ // 16
252
+ function fetch2(url: string, options?: RequestInit): Promise<Response> {
253
+ const id = getLowestKeyIdAvailable(activeFetch2Requests);
254
+
255
+ const headers = options?.headers
256
+ ? options.headers instanceof Headers
257
+ ? JSON.stringify(headersToObject(options.headers))
258
+ : JSON.stringify(options.headers)
259
+ : "";
260
+ const body = options?.body
261
+ ? typeof options.body === "string"
262
+ ? te.encode(options.body)
263
+ : options.body
264
+ : new Uint8Array();
265
+
266
+ if (options?.signal) {
267
+ options.signal.onabort = () => {
268
+ console.log("ABORT REQUEST");
269
+ // cancel
270
+ };
271
+ }
272
+
273
+ const payload = new Uint8Array([
274
+ 16,
275
+
276
+ ...serializeArgs([id, options?.method || "GET", url, headers, body])
277
+ ]);
278
+
279
+ return new Promise<Response>((resolve) => {
280
+ activeFetch2Requests.set(id, {
281
+ url,
282
+ resolveResponse: resolve
283
+ });
284
+ bridge(payload);
285
+ });
286
+ }
287
+
288
+ function objectToHeaders(o: Record<string, string>) {
289
+ const headers = new Headers();
290
+ Object.entries(o).forEach(([n, v]) => {
291
+ headers.set(n, v);
292
+ });
293
+ return headers;
294
+ }
295
+
296
+ const headersToObject = (h: Headers) => {
297
+ const obj = {};
298
+ for (const [n, v] of h.entries()) {
299
+ obj[n] = v;
300
+ }
301
+ return obj;
302
+ };
303
+
304
+ // https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream#convert_an_iterator_or_async_iterator_to_a_stream
305
+ function iteratorToStream(iterator: AsyncIterator<Uint8Array>) {
306
+ return new ReadableStream({
307
+ async pull(controller) {
308
+ const { value, done } = await iterator.next();
309
+
310
+ if (value) {
311
+ controller.enqueue(value);
312
+ }
313
+ if (done) {
314
+ controller.close();
315
+ }
316
+ }
317
+ });
318
+ }