seroval 0.15.0 → 1.0.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.
Files changed (114) hide show
  1. package/README.md +3 -3
  2. package/dist/cjs/development/index.cjs +1278 -1929
  3. package/dist/cjs/development/index.cjs.map +3 -3
  4. package/dist/cjs/production/index.cjs +3 -3
  5. package/dist/esm/development/index.mjs +1278 -1929
  6. package/dist/esm/development/index.mjs.map +3 -3
  7. package/dist/esm/production/index.mjs +3 -3
  8. package/dist/types/core/Serializer.d.ts +2 -1
  9. package/dist/types/core/Serializer.d.ts.map +1 -1
  10. package/dist/types/core/UnsupportedTypeError.d.ts.map +1 -1
  11. package/dist/types/core/base-primitives.d.ts +6 -2
  12. package/dist/types/core/base-primitives.d.ts.map +1 -1
  13. package/dist/types/core/compat.d.ts +5 -13
  14. package/dist/types/core/compat.d.ts.map +1 -1
  15. package/dist/types/core/constants.d.ts +17 -29
  16. package/dist/types/core/constants.d.ts.map +1 -1
  17. package/dist/types/core/context/deserializer.d.ts +6 -16
  18. package/dist/types/core/context/deserializer.d.ts.map +1 -1
  19. package/dist/types/core/context/parser/async.d.ts +2 -11
  20. package/dist/types/core/context/parser/async.d.ts.map +1 -1
  21. package/dist/types/core/context/parser/stream.d.ts +10 -10
  22. package/dist/types/core/context/parser/stream.d.ts.map +1 -1
  23. package/dist/types/core/context/parser/sync.d.ts +5 -7
  24. package/dist/types/core/context/parser/sync.d.ts.map +1 -1
  25. package/dist/types/core/context/parser.d.ts +19 -4
  26. package/dist/types/core/context/parser.d.ts.map +1 -1
  27. package/dist/types/core/context/serializer.d.ts +11 -25
  28. package/dist/types/core/context/serializer.d.ts.map +1 -1
  29. package/dist/types/core/cross/async.d.ts.map +1 -1
  30. package/dist/types/core/cross/deserializer.d.ts.map +1 -1
  31. package/dist/types/core/cross/index.d.ts.map +1 -1
  32. package/dist/types/core/cross/parser.d.ts.map +1 -1
  33. package/dist/types/core/cross/serializer.d.ts +1 -1
  34. package/dist/types/core/cross/serializer.d.ts.map +1 -1
  35. package/dist/types/core/cross/stream.d.ts.map +1 -1
  36. package/dist/types/core/cross/sync.d.ts.map +1 -1
  37. package/dist/types/core/keys.d.ts.map +1 -1
  38. package/dist/types/core/literals.d.ts.map +1 -1
  39. package/dist/types/core/plugin.d.ts +21 -0
  40. package/dist/types/core/plugin.d.ts.map +1 -1
  41. package/dist/types/core/reference.d.ts.map +1 -1
  42. package/dist/types/core/special-reference.d.ts +4 -9
  43. package/dist/types/core/special-reference.d.ts.map +1 -1
  44. package/dist/types/core/stream.d.ts +18 -0
  45. package/dist/types/core/stream.d.ts.map +1 -0
  46. package/dist/types/core/string.d.ts.map +1 -1
  47. package/dist/types/core/tree/async.d.ts.map +1 -1
  48. package/dist/types/core/tree/deserializer.d.ts.map +1 -1
  49. package/dist/types/core/tree/index.d.ts +1 -1
  50. package/dist/types/core/tree/index.d.ts.map +1 -1
  51. package/dist/types/core/tree/serializer.d.ts +3 -11
  52. package/dist/types/core/tree/serializer.d.ts.map +1 -1
  53. package/dist/types/core/types.d.ts +28 -122
  54. package/dist/types/core/types.d.ts.map +1 -1
  55. package/dist/types/core/utils/deferred.d.ts +0 -7
  56. package/dist/types/core/utils/deferred.d.ts.map +1 -1
  57. package/dist/types/core/utils/error.d.ts +2 -1
  58. package/dist/types/core/utils/error.d.ts.map +1 -1
  59. package/dist/types/core/utils/get-identifier.d.ts.map +1 -1
  60. package/dist/types/core/utils/is-valid-identifier.d.ts.map +1 -1
  61. package/dist/types/core/utils/iterator-to-sequence.d.ts +0 -12
  62. package/dist/types/core/utils/iterator-to-sequence.d.ts.map +1 -1
  63. package/dist/types/core/utils/typed-array.d.ts +2 -0
  64. package/dist/types/core/utils/typed-array.d.ts.map +1 -1
  65. package/dist/types/index.d.ts +3 -3
  66. package/dist/types/index.d.ts.map +1 -1
  67. package/package.json +7 -7
  68. package/src/core/Serializer.ts +44 -28
  69. package/src/core/UnsupportedTypeError.ts +2 -3
  70. package/src/core/base-primitives.ts +124 -38
  71. package/src/core/compat.ts +5 -14
  72. package/src/core/constants.ts +28 -39
  73. package/src/core/context/deserializer.ts +122 -308
  74. package/src/core/context/parser/async.ts +163 -375
  75. package/src/core/context/parser/stream.ts +109 -367
  76. package/src/core/context/parser/sync.ts +139 -266
  77. package/src/core/context/parser.ts +93 -68
  78. package/src/core/context/serializer.ts +370 -439
  79. package/src/core/cross/async.ts +1 -1
  80. package/src/core/cross/deserializer.ts +1 -4
  81. package/src/core/cross/index.ts +28 -31
  82. package/src/core/cross/parser.ts +1 -1
  83. package/src/core/cross/serializer.ts +30 -20
  84. package/src/core/cross/stream.ts +1 -1
  85. package/src/core/cross/sync.ts +1 -1
  86. package/src/core/keys.ts +3 -1
  87. package/src/core/literals.ts +22 -8
  88. package/src/core/plugin.ts +48 -10
  89. package/src/core/reference.ts +4 -5
  90. package/src/core/special-reference.ts +5 -15
  91. package/src/core/stream.ts +205 -0
  92. package/src/core/string.ts +53 -22
  93. package/src/core/tree/async.ts +1 -1
  94. package/src/core/tree/deserializer.ts +4 -9
  95. package/src/core/tree/index.ts +15 -10
  96. package/src/core/tree/serializer.ts +6 -50
  97. package/src/core/types.ts +39 -179
  98. package/src/core/utils/deferred.ts +0 -27
  99. package/src/core/utils/error.ts +26 -15
  100. package/src/core/utils/get-identifier.ts +5 -4
  101. package/src/core/utils/is-valid-identifier.ts +6 -5
  102. package/src/core/utils/iterator-to-sequence.ts +0 -174
  103. package/src/core/utils/typed-array.ts +35 -11
  104. package/src/index.ts +5 -12
  105. package/dist/types/core/utils/constructors.d.ts +0 -5
  106. package/dist/types/core/utils/constructors.d.ts.map +0 -1
  107. package/dist/types/core/web-api.d.ts +0 -8
  108. package/dist/types/core/web-api.d.ts.map +0 -1
  109. package/dist/types/types.d.ts +0 -21
  110. package/dist/types/types.d.ts.map +0 -1
  111. package/src/core/utils/constructors.ts +0 -49
  112. package/src/core/web-api.ts +0 -138
  113. package/src/example.ts +0 -25
  114. package/src/types.ts +0 -84
@@ -2,7 +2,7 @@ import BaseAsyncParserContext from '../context/parser/async';
2
2
  import type { CrossParserContextOptions } from './parser';
3
3
  import type { SerovalMode } from '../plugin';
4
4
 
5
- export type CrossAsyncParserContextOptions = CrossParserContextOptions
5
+ export type CrossAsyncParserContextOptions = CrossParserContextOptions;
6
6
 
7
7
  export default class CrossAsyncParserContext extends BaseAsyncParserContext {
8
8
  readonly mode: SerovalMode = 'cross';
@@ -7,10 +7,7 @@ export type CrossDeserializerContextOptions = BaseDeserializerOptions;
7
7
  export default class CrossDeserializerContext extends BaseDeserializerContext {
8
8
  readonly mode: SerovalMode = 'cross';
9
9
 
10
- assignIndexedValue<T>(
11
- index: number,
12
- value: T,
13
- ): T {
10
+ assignIndexedValue<T>(index: number, value: T): T {
14
11
  if (!this.refs.has(index)) {
15
12
  this.refs.set(index, value);
16
13
  }
@@ -1,4 +1,4 @@
1
- import { getCrossReferenceHeader } from '../keys';
1
+ import { resolvePlugins } from '../plugin';
2
2
  import type { SerovalNode } from '../types';
3
3
  import type { CrossAsyncParserContextOptions } from './async';
4
4
  import AsyncCrossParserContext from './async';
@@ -11,54 +11,52 @@ import StreamCrossParserContext from './stream';
11
11
  import type { CrossSyncParserContextOptions } from './sync';
12
12
  import SyncCrossParserContext from './sync';
13
13
 
14
- function insertCrossReferenceHeader(scopeId: string | undefined, value: string): string {
15
- return '(' + getCrossReferenceHeader(scopeId) + ',' + value + ')';
16
- }
17
-
18
14
  export interface CrossSerializeOptions
19
- extends CrossSyncParserContextOptions, CrossContextOptions {
20
- }
15
+ extends CrossSyncParserContextOptions,
16
+ CrossContextOptions {}
21
17
 
22
18
  export function crossSerialize<T>(
23
19
  source: T,
24
20
  options: CrossSerializeOptions = {},
25
21
  ): string {
22
+ const plugins = resolvePlugins(options.plugins);
26
23
  const ctx = new SyncCrossParserContext({
27
- plugins: options.plugins,
24
+ plugins,
28
25
  disabledFeatures: options.disabledFeatures,
29
26
  refs: options.refs,
30
27
  });
31
28
  const tree = ctx.parse(source);
32
29
  const serial = new CrossSerializerContext({
33
- plugins: options.plugins,
30
+ plugins,
34
31
  features: ctx.features,
35
32
  scopeId: options.scopeId,
36
33
  markedRefs: ctx.marked,
37
34
  });
38
- return insertCrossReferenceHeader(options.scopeId, serial.serializeTop(tree));
35
+ return serial.serializeTop(tree);
39
36
  }
40
37
 
41
38
  export interface CrossSerializeAsyncOptions
42
- extends CrossAsyncParserContextOptions, CrossContextOptions {
43
- }
39
+ extends CrossAsyncParserContextOptions,
40
+ CrossContextOptions {}
44
41
 
45
42
  export async function crossSerializeAsync<T>(
46
43
  source: T,
47
44
  options: CrossSerializeAsyncOptions = {},
48
45
  ): Promise<string> {
46
+ const plugins = resolvePlugins(options.plugins);
49
47
  const ctx = new AsyncCrossParserContext({
50
- plugins: options.plugins,
48
+ plugins,
51
49
  disabledFeatures: options.disabledFeatures,
52
50
  refs: options.refs,
53
51
  });
54
52
  const tree = await ctx.parse(source);
55
53
  const serial = new CrossSerializerContext({
56
- plugins: options.plugins,
54
+ plugins,
57
55
  features: ctx.features,
58
56
  scopeId: options.scopeId,
59
57
  markedRefs: ctx.marked,
60
58
  });
61
- return insertCrossReferenceHeader(options.scopeId, serial.serializeTop(tree));
59
+ return serial.serializeTop(tree);
62
60
  }
63
61
 
64
62
  export type ToCrossJSONOptions = CrossParserContextOptions;
@@ -67,8 +65,9 @@ export function toCrossJSON<T>(
67
65
  source: T,
68
66
  options: CrossParserContextOptions = {},
69
67
  ): SerovalNode {
68
+ const plugins = resolvePlugins(options.plugins);
70
69
  const ctx = new SyncCrossParserContext({
71
- plugins: options.plugins,
70
+ plugins,
72
71
  disabledFeatures: options.disabledFeatures,
73
72
  refs: options.refs,
74
73
  });
@@ -81,16 +80,18 @@ export async function toCrossJSONAsync<T>(
81
80
  source: T,
82
81
  options: CrossParserContextOptions = {},
83
82
  ): Promise<SerovalNode> {
83
+ const plugins = resolvePlugins(options.plugins);
84
84
  const ctx = new AsyncCrossParserContext({
85
- plugins: options.plugins,
85
+ plugins,
86
86
  disabledFeatures: options.disabledFeatures,
87
87
  refs: options.refs,
88
88
  });
89
- return ctx.parse(source);
89
+ return await ctx.parse(source);
90
90
  }
91
91
 
92
92
  export interface CrossSerializeStreamOptions
93
- extends Omit<CrossStreamParserContextOptions, 'onParse'>, CrossContextOptions {
93
+ extends Omit<CrossStreamParserContextOptions, 'onParse'>,
94
+ CrossContextOptions {
94
95
  onSerialize: (data: string, initial: boolean) => void;
95
96
  }
96
97
 
@@ -98,13 +99,14 @@ export function crossSerializeStream<T>(
98
99
  source: T,
99
100
  options: CrossSerializeStreamOptions,
100
101
  ): () => void {
102
+ const plugins = resolvePlugins(options.plugins);
101
103
  const ctx = new StreamCrossParserContext({
102
- plugins: options.plugins,
104
+ plugins,
103
105
  refs: options.refs,
104
106
  disabledFeatures: options.disabledFeatures,
105
107
  onParse(node, initial): void {
106
108
  const serial = new CrossSerializerContext({
107
- plugins: options.plugins,
109
+ plugins,
108
110
  features: ctx.features,
109
111
  scopeId: options.scopeId,
110
112
  markedRefs: ctx.marked,
@@ -121,14 +123,7 @@ export function crossSerializeStream<T>(
121
123
  return;
122
124
  }
123
125
 
124
- if (initial) {
125
- serialized = insertCrossReferenceHeader(options.scopeId, serialized);
126
- }
127
-
128
- options.onSerialize(
129
- serialized,
130
- initial,
131
- );
126
+ options.onSerialize(serialized, initial);
132
127
  },
133
128
  onError: options.onError,
134
129
  onDone: options.onDone,
@@ -147,8 +142,9 @@ export function toCrossJSONStream<T>(
147
142
  source: T,
148
143
  options: ToCrossJSONStreamOptions,
149
144
  ): () => void {
145
+ const plugins = resolvePlugins(options.plugins);
150
146
  const ctx = new StreamCrossParserContext({
151
- plugins: options.plugins,
147
+ plugins,
152
148
  refs: options.refs,
153
149
  disabledFeatures: options.disabledFeatures,
154
150
  onParse: options.onParse,
@@ -169,8 +165,9 @@ export function fromCrossJSON<T>(
169
165
  source: SerovalNode,
170
166
  options: FromCrossJSONOptions,
171
167
  ): T {
168
+ const plugins = resolvePlugins(options.plugins);
172
169
  const ctx = new CrossDeserializerContext({
173
- plugins: options.plugins,
170
+ plugins,
174
171
  refs: options.refs,
175
172
  });
176
173
  return ctx.deserialize(source) as T;
@@ -1,6 +1,6 @@
1
1
  import type { BaseParserContextOptions } from '../context/parser';
2
2
 
3
- export type CrossParserContextOptions = BaseParserContextOptions
3
+ export type CrossParserContextOptions = BaseParserContextOptions;
4
4
 
5
5
  export interface CrossContextOptions {
6
6
  scopeId?: string;
@@ -1,9 +1,5 @@
1
- import type {
2
- SerovalNode,
3
- } from '../types';
4
- import {
5
- GLOBAL_CONTEXT_REFERENCES,
6
- } from '../keys';
1
+ import type { SerovalNode } from '../types';
2
+ import { GLOBAL_CONTEXT_REFERENCES } from '../keys';
7
3
  import type { BaseSerializerContextOptions } from '../context/serializer';
8
4
  import BaseSerializerContext from '../context/serializer';
9
5
  import type { SerovalMode } from '../plugin';
@@ -11,8 +7,8 @@ import { serializeString } from '../string';
11
7
  import type { CrossContextOptions } from './parser';
12
8
 
13
9
  export interface CrossSerializerContextOptions
14
- extends BaseSerializerContextOptions, CrossContextOptions {
15
- }
10
+ extends BaseSerializerContextOptions,
11
+ CrossContextOptions {}
16
12
 
17
13
  export default class CrossSerializerContext extends BaseSerializerContext {
18
14
  readonly mode: SerovalMode = 'cross';
@@ -24,35 +20,49 @@ export default class CrossSerializerContext extends BaseSerializerContext {
24
20
  this.scopeId = options.scopeId;
25
21
  }
26
22
 
27
- getRefParam(id: number | string): string {
28
- if (typeof id === 'string') {
29
- return GLOBAL_CONTEXT_REFERENCES + '.' + id;
30
- }
23
+ getRefParam(id: number): string {
31
24
  return GLOBAL_CONTEXT_REFERENCES + '[' + id + ']';
32
25
  }
33
26
 
34
- protected assignIndexedValue(
35
- index: number,
36
- value: string,
37
- ): string {
27
+ protected assignIndexedValue(index: number, value: string): string {
28
+ // In cross-reference, we have to assume that
29
+ // every reference are going to be referenced
30
+ // in the future, and so we need to store
31
+ // all of it into the reference array.
38
32
  return this.getRefParam(index) + '=' + value;
39
33
  }
40
34
 
41
35
  serializeTop(tree: SerovalNode): string {
36
+ // Get the serialized result
42
37
  const result = this.serialize(tree);
38
+ // If the node is a non-reference, return
39
+ // the result immediately
43
40
  const id = tree.i;
44
41
  if (id == null) {
45
42
  return result;
46
43
  }
44
+ // Get the patches
47
45
  const patches = this.resolvePatches();
46
+ // Get the variable that represents the root
48
47
  const ref = this.getRefParam(id);
48
+ // Parameters needed for scoping
49
49
  const params = this.scopeId == null ? '' : GLOBAL_CONTEXT_REFERENCES;
50
- const mainBody = patches ? result + ',' + patches : result;
50
+ // If there are patches, append it after the result
51
+ const body = patches ? result + ',' + patches + ref : result;
52
+ // If there are no params, there's no need to generate a function
51
53
  if (params === '') {
52
- return patches ? '(' + mainBody + ref + ')' : mainBody;
54
+ return patches ? '(' + body + ')' : body;
53
55
  }
54
- const args = this.scopeId == null ? '()' : '(' + GLOBAL_CONTEXT_REFERENCES + '["' + serializeString(this.scopeId) + '"])';
55
- const body = mainBody + (patches ? ref : '');
56
+ // Get the arguments for the IIFE
57
+ const args =
58
+ this.scopeId == null
59
+ ? '()'
60
+ : '(' +
61
+ GLOBAL_CONTEXT_REFERENCES +
62
+ '["' +
63
+ serializeString(this.scopeId) +
64
+ '"])';
65
+ // Create the IIFE
56
66
  return '(' + this.createFunction([params], body) + ')' + args;
57
67
  }
58
68
  }
@@ -2,7 +2,7 @@ import type { BaseStreamParserContextOptions } from '../context/parser/stream';
2
2
  import BaseStreamParserContext from '../context/parser/stream';
3
3
  import type { SerovalMode } from '../plugin';
4
4
 
5
- export type CrossStreamParserContextOptions = BaseStreamParserContextOptions
5
+ export type CrossStreamParserContextOptions = BaseStreamParserContextOptions;
6
6
 
7
7
  export default class CrossStreamParserContext extends BaseStreamParserContext {
8
8
  readonly mode: SerovalMode = 'cross';
@@ -2,7 +2,7 @@ import BaseSyncParserContext from '../context/parser/sync';
2
2
  import type { SerovalMode } from '../plugin';
3
3
  import type { CrossParserContextOptions } from './parser';
4
4
 
5
- export type CrossSyncParserContextOptions = CrossParserContextOptions
5
+ export type CrossSyncParserContextOptions = CrossParserContextOptions;
6
6
 
7
7
  export default class CrossSyncParserContext extends BaseSyncParserContext {
8
8
  readonly mode: SerovalMode = 'cross';
package/src/core/keys.ts CHANGED
@@ -11,5 +11,7 @@ export function getCrossReferenceHeader(id?: string): string {
11
11
  if (id == null) {
12
12
  return `${GLOBAL_CONTEXT_R}=${GLOBAL_CONTEXT_R}||[]`;
13
13
  }
14
- return `(${GLOBAL_CONTEXT_R}=${GLOBAL_CONTEXT_R}||{})["${serializeString(id)}"]=[]`;
14
+ return `(${GLOBAL_CONTEXT_R}=${GLOBAL_CONTEXT_R}||{})["${serializeString(
15
+ id,
16
+ )}"]=[]`;
15
17
  }
@@ -18,11 +18,25 @@ function createConstantNode(value: SerovalConstant): SerovalConstantNode {
18
18
  };
19
19
  }
20
20
 
21
- export const TRUE_NODE = createConstantNode(SerovalConstant.True);
22
- export const FALSE_NODE = createConstantNode(SerovalConstant.False);
23
- export const UNDEFINED_NODE = createConstantNode(SerovalConstant.Undefined);
24
- export const NULL_NODE = createConstantNode(SerovalConstant.Null);
25
- export const NEG_ZERO_NODE = createConstantNode(SerovalConstant.NegativeZero);
26
- export const INFINITY_NODE = createConstantNode(SerovalConstant.Infinity);
27
- export const NEG_INFINITY_NODE = createConstantNode(SerovalConstant.NegativeInfinity);
28
- export const NAN_NODE = createConstantNode(SerovalConstant.NaN);
21
+ export const TRUE_NODE = /* @__PURE__ */ createConstantNode(
22
+ SerovalConstant.True,
23
+ );
24
+ export const FALSE_NODE = /* @__PURE__ */ createConstantNode(
25
+ SerovalConstant.False,
26
+ );
27
+ export const UNDEFINED_NODE = /* @__PURE__ */ createConstantNode(
28
+ SerovalConstant.Undefined,
29
+ );
30
+ export const NULL_NODE = /* @__PURE__ */ createConstantNode(
31
+ SerovalConstant.Null,
32
+ );
33
+ export const NEG_ZERO_NODE = /* @__PURE__ */ createConstantNode(
34
+ SerovalConstant.NegativeZero,
35
+ );
36
+ export const INFINITY_NODE = /* @__PURE__ */ createConstantNode(
37
+ SerovalConstant.Infinity,
38
+ );
39
+ export const NEG_INFINITY_NODE = /* @__PURE__ */ createConstantNode(
40
+ SerovalConstant.NegativeInfinity,
41
+ );
42
+ export const NAN_NODE = /* @__PURE__ */ createConstantNode(SerovalConstant.NaN);
@@ -11,14 +11,24 @@ export interface PluginData {
11
11
  }
12
12
 
13
13
  export interface Plugin<Value, Node> {
14
+ /**
15
+ * A unique string that helps idenfity the plugin
16
+ */
14
17
  tag: string;
18
+ /**
19
+ * List of dependency plugins
20
+ */
21
+ extends?: Plugin<any, any>[];
22
+ /**
23
+ * Method to test if a value is an expected value of the plugin
24
+ * @param value
25
+ */
15
26
  test(value: unknown): boolean;
27
+ /**
28
+ * Parsing modes
29
+ */
16
30
  parse: {
17
- sync?: (
18
- value: Value,
19
- ctx: BaseSyncParserContext,
20
- data: PluginData,
21
- ) => Node;
31
+ sync?: (value: Value, ctx: BaseSyncParserContext, data: PluginData) => Node;
22
32
  async?: (
23
33
  value: Value,
24
34
  ctx: BaseAsyncParserContext,
@@ -30,11 +40,13 @@ export interface Plugin<Value, Node> {
30
40
  data: PluginData,
31
41
  ) => Node;
32
42
  };
33
- serialize(
34
- node: Node,
35
- ctx: BaseSerializerContext,
36
- data: PluginData,
37
- ): string;
43
+ /**
44
+ * Convert the parsed node into a JS string
45
+ */
46
+ serialize(node: Node, ctx: BaseSerializerContext, data: PluginData): string;
47
+ /**
48
+ * Convert the parsed node into its runtime equivalent.
49
+ */
38
50
  deserialize(
39
51
  node: Node,
40
52
  ctx: BaseDeserializerContext,
@@ -51,3 +63,29 @@ export function createPlugin<Value, Node>(
51
63
  export interface PluginAccessOptions {
52
64
  plugins?: Plugin<any, any>[];
53
65
  }
66
+
67
+ function dedupePlugins(
68
+ deduped: Set<Plugin<any, any>>,
69
+ plugins: Plugin<any, any>[],
70
+ ): void {
71
+ for (let i = 0, len = plugins.length; i < len; i++) {
72
+ const current = plugins[i];
73
+ if (!deduped.has(current)) {
74
+ deduped.add(current);
75
+ if (current.extends) {
76
+ dedupePlugins(deduped, current.extends);
77
+ }
78
+ }
79
+ }
80
+ }
81
+
82
+ export function resolvePlugins(
83
+ plugins?: Plugin<any, any>[],
84
+ ): Plugin<any, any>[] | undefined {
85
+ if (plugins) {
86
+ const deduped = new Set<Plugin<any, any>>();
87
+ dedupePlugins(deduped, plugins);
88
+ return [...deduped];
89
+ }
90
+ return undefined;
91
+ }
@@ -1,4 +1,3 @@
1
- /* eslint-disable no-restricted-globals */
2
1
  import assert from './utils/assert';
3
2
  import { REFERENCES_KEY } from './keys';
4
3
 
@@ -29,28 +28,28 @@ export function getReference<T>(id: string): T {
29
28
  return INV_REFERENCE.get(id) as T;
30
29
  }
31
30
 
32
- if (typeof globalThis !== undefined) {
31
+ if (typeof globalThis !== 'undefined') {
33
32
  Object.defineProperty(globalThis, REFERENCES_KEY, {
34
33
  value: INV_REFERENCE,
35
34
  configurable: true,
36
35
  writable: false,
37
36
  enumerable: false,
38
37
  });
39
- } else if (typeof window !== undefined) {
38
+ } else if (typeof window !== 'undefined') {
40
39
  Object.defineProperty(window, REFERENCES_KEY, {
41
40
  value: INV_REFERENCE,
42
41
  configurable: true,
43
42
  writable: false,
44
43
  enumerable: false,
45
44
  });
46
- } else if (typeof self !== undefined) {
45
+ } else if (typeof self !== 'undefined') {
47
46
  Object.defineProperty(self, REFERENCES_KEY, {
48
47
  value: INV_REFERENCE,
49
48
  configurable: true,
50
49
  writable: false,
51
50
  enumerable: false,
52
51
  });
53
- } else if (typeof global !== undefined) {
52
+ } else if (typeof global !== 'undefined') {
54
53
  Object.defineProperty(global, REFERENCES_KEY, {
55
54
  value: INV_REFERENCE,
56
55
  configurable: true,
@@ -1,29 +1,19 @@
1
- export const UNIVERSAL_SENTINEL = {};
2
-
3
1
  export const ITERATOR = {};
4
2
 
5
3
  export const ASYNC_ITERATOR = {};
6
4
 
7
5
  export const enum SpecialReference {
8
6
  MapSentinel = 0,
9
- ReadableStream = 1,
10
- PromiseConstructor = 2,
11
- PromiseResolve = 3,
12
- PromiseReject = 4,
13
- ReadableStreamConstructor = 5,
14
- ReadableStreamEnqueue = 6,
15
- ReadableStreamError = 7,
16
- ReadableStreamClose = 8,
7
+ PromiseConstructor = 1,
8
+ PromiseResolve = 2,
9
+ PromiseReject = 3,
10
+ StreamConstructor = 4,
17
11
  }
18
12
 
19
13
  export const SPECIAL_REFS: Record<SpecialReference, unknown> = {
20
14
  [SpecialReference.MapSentinel]: {},
21
- [SpecialReference.ReadableStream]: {},
22
15
  [SpecialReference.PromiseConstructor]: {},
23
16
  [SpecialReference.PromiseResolve]: {},
24
17
  [SpecialReference.PromiseReject]: {},
25
- [SpecialReference.ReadableStreamConstructor]: {},
26
- [SpecialReference.ReadableStreamEnqueue]: {},
27
- [SpecialReference.ReadableStreamError]: {},
28
- [SpecialReference.ReadableStreamClose]: {},
18
+ [SpecialReference.StreamConstructor]: {},
29
19
  };