seroval-plugins 1.4.0 → 1.5.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.
@@ -1,114 +1,65 @@
1
1
  import type { SerovalNode } from 'seroval';
2
2
  import { createPlugin } from 'seroval';
3
3
 
4
+ const PROMISE_TO_ABORT_SIGNAL = (promise: Promise<unknown>) => {
5
+ const controller = new AbortController();
6
+ const abort = controller.abort.bind(controller);
7
+ promise.then(abort, abort);
8
+ return controller;
9
+ };
10
+
4
11
  function resolveAbortSignalResult(
5
12
  this: AbortSignal,
6
- resolve: (value: any) => void,
13
+ resolve: (value: unknown) => void,
7
14
  ): void {
8
15
  resolve(this.reason);
9
16
  }
10
17
 
11
18
  function resolveAbortSignal(
12
19
  this: AbortSignal,
13
- resolve: (value: any) => void,
20
+ resolve: (value: unknown) => void,
14
21
  ): void {
15
22
  this.addEventListener('abort', resolveAbortSignalResult.bind(this, resolve), {
16
23
  once: true,
17
24
  });
18
25
  }
19
26
 
20
- export function abortSignalToPromise(signal: AbortSignal): Promise<any> {
27
+ function abortSignalToPromise(signal: AbortSignal): Promise<unknown> {
21
28
  return new Promise(resolveAbortSignal.bind(signal));
22
29
  }
23
30
 
24
- class AbortSignalController {
25
- controller = new AbortController();
26
- }
31
+ const ABORT_CONTROLLER = {};
27
32
 
28
- const AbortSignalControllerPlugin = createPlugin<
29
- AbortSignalController,
30
- undefined
31
- >({
32
- tag: 'seroval-plugins/web/AbortSignalController',
33
+ const AbortControllerFactoryPlugin = /* @__PURE__ */ createPlugin<object, {}>({
34
+ tag: 'seroval-plugins/web/AbortControllerFactoryPlugin',
33
35
  test(value) {
34
- // We didn't actually use the AbortController class
35
- // directly because of some assumptions
36
- return value instanceof AbortSignalController;
36
+ return value === ABORT_CONTROLLER;
37
37
  },
38
38
  parse: {
39
+ sync() {
40
+ return ABORT_CONTROLLER;
41
+ },
42
+ async async() {
43
+ return await Promise.resolve(ABORT_CONTROLLER);
44
+ },
39
45
  stream() {
40
- return undefined;
46
+ return ABORT_CONTROLLER;
41
47
  },
42
48
  },
43
- serialize(_node) {
44
- return 'new AbortController';
49
+ serialize() {
50
+ return PROMISE_TO_ABORT_SIGNAL.toString();
45
51
  },
46
- deserialize(_node) {
47
- return new AbortSignalController();
52
+ deserialize() {
53
+ return PROMISE_TO_ABORT_SIGNAL;
48
54
  },
49
55
  });
50
56
 
51
- interface AbortSignalAbortNode {
52
- controller: SerovalNode;
53
- reason: SerovalNode;
54
- }
55
-
56
- class AbortSignalAbort {
57
- constructor(
58
- public controller: AbortSignalController,
59
- public reason: unknown,
60
- ) {}
61
- }
62
-
63
- const AbortSignalAbortPlugin = createPlugin<
64
- AbortSignalAbort,
65
- AbortSignalAbortNode
57
+ const AbortSignalPlugin = /* @__PURE__ */ createPlugin<
58
+ AbortSignal,
59
+ { reason?: SerovalNode; controller?: SerovalNode; factory?: SerovalNode }
66
60
  >({
67
- extends: [AbortSignalControllerPlugin],
68
- tag: 'seroval-plugins/web/AbortSignalAbort',
69
- test(value) {
70
- return value instanceof AbortSignalAbort;
71
- },
72
- parse: {
73
- stream(value, ctx) {
74
- return {
75
- controller: ctx.parse(value.controller),
76
- reason: ctx.parse(value.reason),
77
- };
78
- },
79
- },
80
- serialize(node, ctx) {
81
- return (
82
- ctx.serialize(node.controller) +
83
- '.abort(' +
84
- ctx.serialize(node.reason) +
85
- ')'
86
- );
87
- },
88
- deserialize(node, ctx) {
89
- const controller = ctx.deserialize(
90
- node.controller,
91
- ) as AbortSignalController;
92
- const reason = ctx.deserialize(node.reason);
93
- controller.controller.abort(reason);
94
- return new AbortSignalAbort(controller, reason);
95
- },
96
- });
97
-
98
- const enum AbortSignalState {
99
- Pending = 0,
100
- Aborted = 1,
101
- Streaming = 2,
102
- }
103
-
104
- type AbortSignalNode =
105
- | { type: AbortSignalState.Pending }
106
- | { type: AbortSignalState.Aborted; reason: SerovalNode }
107
- | { type: AbortSignalState.Streaming; controller: SerovalNode };
108
-
109
- const AbortSignalPlugin = createPlugin<AbortSignal, AbortSignalNode>({
110
61
  tag: 'seroval-plugins/web/AbortSignal',
111
- extends: [AbortSignalAbortPlugin],
62
+ extends: [AbortControllerFactoryPlugin],
112
63
  test(value) {
113
64
  if (typeof AbortSignal === 'undefined') {
114
65
  return false;
@@ -119,78 +70,61 @@ const AbortSignalPlugin = createPlugin<AbortSignal, AbortSignalNode>({
119
70
  sync(value, ctx) {
120
71
  if (value.aborted) {
121
72
  return {
122
- type: AbortSignalState.Aborted,
123
73
  reason: ctx.parse(value.reason),
124
74
  };
125
75
  }
126
- return {
127
- type: AbortSignalState.Pending,
128
- };
76
+ return {};
129
77
  },
130
78
  async async(value, ctx) {
131
79
  if (value.aborted) {
132
80
  return {
133
- type: AbortSignalState.Aborted,
134
81
  reason: await ctx.parse(value.reason),
135
82
  };
136
83
  }
137
84
  const result = await abortSignalToPromise(value);
138
85
  return {
139
- type: AbortSignalState.Aborted,
140
86
  reason: await ctx.parse(result),
141
87
  };
142
88
  },
143
89
  stream(value, ctx) {
144
90
  if (value.aborted) {
145
91
  return {
146
- type: AbortSignalState.Aborted,
147
92
  reason: ctx.parse(value.reason),
148
93
  };
149
94
  }
150
- const controller = new AbortSignalController();
151
95
 
152
- ctx.pushPendingState();
153
- value.addEventListener(
154
- 'abort',
155
- () => {
156
- const result = ctx.parseWithError(
157
- new AbortSignalAbort(controller, value.reason),
158
- );
159
- if (result) {
160
- ctx.onParse(result);
161
- }
162
- ctx.popPendingState();
163
- },
164
- { once: true },
165
- );
96
+ const promise = abortSignalToPromise(value);
166
97
 
167
98
  return {
168
- type: AbortSignalState.Streaming,
169
- controller: ctx.parse(controller),
99
+ factory: ctx.parse(ABORT_CONTROLLER),
100
+ controller: ctx.parse(promise),
170
101
  };
171
102
  },
172
103
  },
173
104
  serialize(node, ctx) {
174
- if (node.type === AbortSignalState.Pending) {
175
- return '(new AbortController).signal';
176
- }
177
- if (node.type === AbortSignalState.Aborted) {
105
+ if (node.reason) {
178
106
  return 'AbortSignal.abort(' + ctx.serialize(node.reason) + ')';
179
107
  }
180
- return '(' + ctx.serialize(node.controller) + ').signal';
108
+ if (node.controller && node.factory) {
109
+ return (
110
+ '(' +
111
+ ctx.serialize(node.factory) +
112
+ ')(' +
113
+ ctx.serialize(node.controller) +
114
+ ').signal'
115
+ );
116
+ }
117
+ return '(new AbortController).signal';
181
118
  },
182
119
  deserialize(node, ctx) {
183
- if (node.type === AbortSignalState.Pending) {
184
- const controller = new AbortController();
185
- return controller.signal;
186
- }
187
- if (node.type === AbortSignalState.Aborted) {
120
+ if (node.reason) {
188
121
  return AbortSignal.abort(ctx.deserialize(node.reason));
189
122
  }
190
- const controller = ctx.deserialize(
191
- node.controller,
192
- ) as AbortSignalController;
193
- return controller.controller.signal;
123
+ if (node.controller) {
124
+ return PROMISE_TO_ABORT_SIGNAL(ctx.deserialize(node.controller)).signal;
125
+ }
126
+ const controller = new AbortController();
127
+ return controller.signal;
194
128
  },
195
129
  });
196
130
 
package/web/blob.ts CHANGED
@@ -1,10 +1,10 @@
1
1
  import type { SerovalNode } from 'seroval';
2
2
  import { createPlugin } from 'seroval';
3
3
 
4
- interface BlobNode {
4
+ type BlobNode = {
5
5
  type: SerovalNode;
6
6
  buffer: SerovalNode;
7
- }
7
+ };
8
8
 
9
9
  const BlobPlugin = /* @__PURE__ */ createPlugin<Blob, BlobNode>({
10
10
  tag: 'seroval-plugins/web/Blob',
@@ -10,10 +10,10 @@ function createCustomEventOptions(current: CustomEvent): CustomEventInit {
10
10
  };
11
11
  }
12
12
 
13
- interface CustomEventNode {
13
+ type CustomEventNode = {
14
14
  type: SerovalNode;
15
15
  options: SerovalNode;
16
- }
16
+ };
17
17
 
18
18
  const CustomEventPlugin = /* @__PURE__ */ createPlugin<
19
19
  CustomEvent,
@@ -1,10 +1,10 @@
1
1
  import type { SerovalNode } from 'seroval';
2
2
  import { createPlugin } from 'seroval';
3
3
 
4
- interface DOMExceptionNode {
4
+ type DOMExceptionNode = {
5
5
  name: SerovalNode;
6
6
  message: SerovalNode;
7
- }
7
+ };
8
8
 
9
9
  const DOMExceptionPlugin = /* @__PURE__ */ createPlugin<
10
10
  DOMException,
package/web/event.ts CHANGED
@@ -9,10 +9,10 @@ function createEventOptions(current: Event): EventInit {
9
9
  };
10
10
  }
11
11
 
12
- interface EventNode {
12
+ type EventNode = {
13
13
  type: SerovalNode;
14
14
  options: SerovalNode;
15
- }
15
+ };
16
16
 
17
17
  const EventPlugin = /* @__PURE__ */ createPlugin<Event, EventNode>({
18
18
  tag: 'seroval-plugins/web/Event',
package/web/file.ts CHANGED
@@ -1,11 +1,11 @@
1
1
  import type { SerovalNode } from 'seroval';
2
2
  import { createPlugin } from 'seroval';
3
3
 
4
- interface FileNode {
4
+ type FileNode = {
5
5
  name: SerovalNode;
6
6
  options: SerovalNode;
7
7
  buffer: SerovalNode;
8
- }
8
+ };
9
9
 
10
10
  const FilePlugin = /* @__PURE__ */ createPlugin<File, FileNode>({
11
11
  tag: 'seroval-plugins/web/File',
package/web/form-data.ts CHANGED
@@ -28,20 +28,20 @@ const FORM_DATA_FACTORY_CONSTRUCTOR = (
28
28
  return f;
29
29
  };
30
30
 
31
- const FormDataFactoryPlugin = /* @__PURE__ */ createPlugin<object, undefined>({
31
+ const FormDataFactoryPlugin = /* @__PURE__ */ createPlugin<object, {}>({
32
32
  tag: 'seroval-plugins/web/FormDataFactory',
33
33
  test(value) {
34
34
  return value === FORM_DATA_FACTORY;
35
35
  },
36
36
  parse: {
37
37
  sync() {
38
- return undefined;
38
+ return FORM_DATA_FACTORY;
39
39
  },
40
40
  async async() {
41
- return await Promise.resolve(undefined);
41
+ return await Promise.resolve(FORM_DATA_FACTORY);
42
42
  },
43
43
  stream() {
44
- return undefined;
44
+ return FORM_DATA_FACTORY;
45
45
  },
46
46
  },
47
47
  serialize() {
@@ -52,10 +52,10 @@ const FormDataFactoryPlugin = /* @__PURE__ */ createPlugin<object, undefined>({
52
52
  },
53
53
  });
54
54
 
55
- interface FormDataNode {
55
+ type FormDataNode = {
56
56
  factory: SerovalNode;
57
57
  entries: SerovalNode;
58
- }
58
+ };
59
59
 
60
60
  const FormDataPlugin = /* @__PURE__ */ createPlugin<FormData, FormDataNode>({
61
61
  tag: 'seroval-plugins/web/FormData',
package/web/headers.ts CHANGED
@@ -10,7 +10,10 @@ function convertHeaders(instance: Headers): HeadersInit {
10
10
  return items;
11
11
  }
12
12
 
13
- const HeadersPlugin = /* @__PURE__ */ createPlugin<Headers, SerovalNode>({
13
+ const HeadersPlugin = /* @__PURE__ */ createPlugin<
14
+ Headers,
15
+ { value: SerovalNode }
16
+ >({
14
17
  tag: 'seroval-plugins/web/Headers',
15
18
  test(value) {
16
19
  if (typeof Headers === 'undefined') {
@@ -20,20 +23,26 @@ const HeadersPlugin = /* @__PURE__ */ createPlugin<Headers, SerovalNode>({
20
23
  },
21
24
  parse: {
22
25
  sync(value, ctx) {
23
- return ctx.parse(convertHeaders(value));
26
+ return {
27
+ value: ctx.parse(convertHeaders(value)),
28
+ };
24
29
  },
25
30
  async async(value, ctx) {
26
- return await ctx.parse(convertHeaders(value));
31
+ return {
32
+ value: await ctx.parse(convertHeaders(value)),
33
+ };
27
34
  },
28
35
  stream(value, ctx) {
29
- return ctx.parse(convertHeaders(value));
36
+ return {
37
+ value: ctx.parse(convertHeaders(value)),
38
+ };
30
39
  },
31
40
  },
32
41
  serialize(node, ctx) {
33
- return 'new Headers(' + ctx.serialize(node) + ')';
42
+ return 'new Headers(' + ctx.serialize(node.value) + ')';
34
43
  },
35
44
  deserialize(node, ctx) {
36
- return new Headers(ctx.deserialize(node) as HeadersInit);
45
+ return new Headers(ctx.deserialize(node.value) as HeadersInit);
37
46
  },
38
47
  });
39
48
 
package/web/image-data.ts CHANGED
@@ -1,12 +1,12 @@
1
1
  import type { SerovalNode } from 'seroval';
2
2
  import { createPlugin } from 'seroval';
3
3
 
4
- interface ImageDataNode {
4
+ type ImageDataNode = {
5
5
  data: SerovalNode;
6
6
  width: SerovalNode;
7
7
  height: SerovalNode;
8
8
  options: SerovalNode;
9
- }
9
+ };
10
10
 
11
11
  const ImageDataPlugin = /* @__PURE__ */ createPlugin<ImageData, ImageDataNode>({
12
12
  tag: 'seroval-plugins/web/ImageData',
@@ -3,33 +3,34 @@ import { createPlugin, createStream } from 'seroval';
3
3
 
4
4
  const READABLE_STREAM_FACTORY = {};
5
5
 
6
- const READABLE_STREAM_FACTORY_CONSTRUCTOR = (stream: Stream<unknown>) => new ReadableStream({
7
- start: (controller) => {
8
- stream.on({
9
- next: (value) => {
10
- try {
11
- controller.enqueue(value)
12
- } catch (_error) {
13
- // no-op
14
- }
15
- },
16
- throw: (value) => {
17
- controller.error(value);
18
- },
19
- return: () => {
20
- try {
21
- controller.close();
22
- } catch (_error) {
23
- // no-op
24
- }
25
- },
26
- })
27
- },
28
- });
6
+ const READABLE_STREAM_FACTORY_CONSTRUCTOR = (stream: Stream<unknown>) =>
7
+ new ReadableStream({
8
+ start: controller => {
9
+ stream.on({
10
+ next: value => {
11
+ try {
12
+ controller.enqueue(value);
13
+ } catch (_error) {
14
+ // no-op
15
+ }
16
+ },
17
+ throw: value => {
18
+ controller.error(value);
19
+ },
20
+ return: () => {
21
+ try {
22
+ controller.close();
23
+ } catch (_error) {
24
+ // no-op
25
+ }
26
+ },
27
+ });
28
+ },
29
+ });
29
30
 
30
31
  const ReadableStreamFactoryPlugin = /* @__PURE__ */ createPlugin<
31
32
  object,
32
- undefined
33
+ {}
33
34
  >({
34
35
  tag: 'seroval-plugins/web/ReadableStreamFactory',
35
36
  test(value) {
@@ -37,13 +38,13 @@ const ReadableStreamFactoryPlugin = /* @__PURE__ */ createPlugin<
37
38
  },
38
39
  parse: {
39
40
  sync() {
40
- return undefined;
41
+ return READABLE_STREAM_FACTORY;
41
42
  },
42
43
  async async() {
43
- return await Promise.resolve(undefined);
44
+ return await Promise.resolve(READABLE_STREAM_FACTORY);
44
45
  },
45
46
  stream() {
46
- return undefined;
47
+ return READABLE_STREAM_FACTORY;
47
48
  },
48
49
  },
49
50
  serialize() {
@@ -80,10 +81,10 @@ function toStream<T>(value: ReadableStream<T>): Stream<T | undefined> {
80
81
  return stream;
81
82
  }
82
83
 
83
- interface ReadableStreamNode {
84
+ type ReadableStreamNode = {
84
85
  factory: SerovalNode;
85
86
  stream: SerovalNode;
86
- }
87
+ };
87
88
 
88
89
  const ReadableStreamPlugin = /* @__PURE__ */ createPlugin<
89
90
  ReadableStream,
package/web/request.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import type { SerovalNode } from 'seroval';
2
2
  import { createPlugin } from 'seroval';
3
- import ReadableStreamPlugin from './readable-stream';
4
3
  import HeadersPlugin from './headers';
4
+ import ReadableStreamPlugin from './readable-stream';
5
5
 
6
6
  function createRequestOptions(
7
7
  current: Request,
@@ -22,10 +22,10 @@ function createRequestOptions(
22
22
  };
23
23
  }
24
24
 
25
- interface RequestNode {
25
+ type RequestNode = {
26
26
  url: SerovalNode;
27
27
  options: SerovalNode;
28
- }
28
+ };
29
29
 
30
30
  const RequestPlugin = /* @__PURE__ */ createPlugin<Request, RequestNode>({
31
31
  tag: 'seroval-plugins/web/Request',
package/web/response.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import type { SerovalNode } from 'seroval';
2
2
  import { createPlugin } from 'seroval';
3
- import ReadableStreamPlugin from './readable-stream';
4
3
  import HeadersPlugin from './headers';
4
+ import ReadableStreamPlugin from './readable-stream';
5
5
 
6
6
  function createResponseOptions(current: Response): ResponseInit {
7
7
  return {
@@ -11,10 +11,10 @@ function createResponseOptions(current: Response): ResponseInit {
11
11
  };
12
12
  }
13
13
 
14
- interface ResponseNode {
14
+ type ResponseNode = {
15
15
  body: SerovalNode;
16
16
  options: SerovalNode;
17
- }
17
+ };
18
18
 
19
19
  const ResponsePlugin = /* @__PURE__ */ createPlugin<Response, ResponseNode>({
20
20
  tag: 'seroval-plugins/web/Response',
@@ -3,7 +3,7 @@ import { createPlugin } from 'seroval';
3
3
 
4
4
  const URLSearchParamsPlugin = /* @__PURE__ */ createPlugin<
5
5
  URLSearchParams,
6
- SerovalNode
6
+ { value: SerovalNode }
7
7
  >({
8
8
  tag: 'seroval-plugins/web/URLSearchParams',
9
9
  test(value) {
@@ -14,20 +14,26 @@ const URLSearchParamsPlugin = /* @__PURE__ */ createPlugin<
14
14
  },
15
15
  parse: {
16
16
  sync(value, ctx) {
17
- return ctx.parse(value.toString());
17
+ return {
18
+ value: ctx.parse(value.toString()),
19
+ };
18
20
  },
19
21
  async async(value, ctx) {
20
- return await ctx.parse(value.toString());
22
+ return {
23
+ value: await ctx.parse(value.toString()),
24
+ };
21
25
  },
22
26
  stream(value, ctx) {
23
- return ctx.parse(value.toString());
27
+ return {
28
+ value: ctx.parse(value.toString()),
29
+ };
24
30
  },
25
31
  },
26
32
  serialize(node, ctx) {
27
- return 'new URLSearchParams(' + ctx.serialize(node) + ')';
33
+ return 'new URLSearchParams(' + ctx.serialize(node.value) + ')';
28
34
  },
29
35
  deserialize(node, ctx) {
30
- return new URLSearchParams(ctx.deserialize(node) as string);
36
+ return new URLSearchParams(ctx.deserialize(node.value) as string);
31
37
  },
32
38
  });
33
39
 
package/web/url.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import type { SerovalNode } from 'seroval';
2
2
  import { createPlugin } from 'seroval';
3
3
 
4
- const URLPlugin = /* @__PURE__ */ createPlugin<URL, SerovalNode>({
4
+ const URLPlugin = /* @__PURE__ */ createPlugin<URL, { value: SerovalNode }>({
5
5
  tag: 'seroval-plugins/web/URL',
6
6
  test(value) {
7
7
  if (typeof URL === 'undefined') {
@@ -11,20 +11,26 @@ const URLPlugin = /* @__PURE__ */ createPlugin<URL, SerovalNode>({
11
11
  },
12
12
  parse: {
13
13
  sync(value, ctx) {
14
- return ctx.parse(value.href);
14
+ return {
15
+ value: ctx.parse(value.href),
16
+ };
15
17
  },
16
18
  async async(value, ctx) {
17
- return await ctx.parse(value.href);
19
+ return {
20
+ value: await ctx.parse(value.href),
21
+ };
18
22
  },
19
23
  stream(value, ctx) {
20
- return ctx.parse(value.href);
24
+ return {
25
+ value: ctx.parse(value.href),
26
+ };
21
27
  },
22
28
  },
23
29
  serialize(node, ctx) {
24
- return 'new URL(' + ctx.serialize(node) + ')';
30
+ return 'new URL(' + ctx.serialize(node.value) + ')';
25
31
  },
26
32
  deserialize(node, ctx) {
27
- return new URL(ctx.deserialize(node) as string);
33
+ return new URL(ctx.deserialize(node.value) as string);
28
34
  },
29
35
  });
30
36