adnbn 0.12.0 → 0.13.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 (128) hide show
  1. package/dist/cli/bundler/layers.d.ts +3 -3
  2. package/dist/cli/bundler/layers.js +6 -7
  3. package/dist/cli/bundler/layers.js.map +1 -1
  4. package/dist/cli/bundler/plugins/build-assets-map/BuildAssetsMapPlugin.js +42 -14
  5. package/dist/cli/bundler/plugins/build-assets-map/BuildAssetsMapPlugin.js.map +1 -1
  6. package/dist/cli/bundler/plugins/build-assets-map/normalize.d.ts +3 -0
  7. package/dist/cli/bundler/plugins/build-assets-map/normalize.js +24 -0
  8. package/dist/cli/bundler/plugins/build-assets-map/normalize.js.map +1 -0
  9. package/dist/cli/bundler/plugins/build-assets-map/templates/runtime.template.d.ts +2 -0
  10. package/dist/cli/bundler/plugins/build-assets-map/templates.d.ts +9 -0
  11. package/dist/cli/bundler/plugins/build-assets-map/templates.js +32 -0
  12. package/dist/cli/bundler/plugins/entrypoint/EntrypointPlugin.js +11 -0
  13. package/dist/cli/bundler/plugins/entrypoint/EntrypointPlugin.js.map +1 -1
  14. package/dist/cli/bundler/plugins/isolated-styles/IsolatedStylesPlugin.d.ts +1 -1
  15. package/dist/cli/bundler/plugins/isolated-styles/IsolatedStylesPlugin.js +38 -13
  16. package/dist/cli/bundler/plugins/isolated-styles/IsolatedStylesPlugin.js.map +1 -1
  17. package/dist/cli/bundler/plugins/isolated-styles/chunks.d.ts +5 -1
  18. package/dist/cli/bundler/plugins/isolated-styles/chunks.js +17 -16
  19. package/dist/cli/bundler/plugins/isolated-styles/chunks.js.map +1 -1
  20. package/dist/cli/bundler/plugins/isolated-styles/split-chunks.d.ts +4 -0
  21. package/dist/cli/bundler/plugins/isolated-styles/split-chunks.js +51 -0
  22. package/dist/cli/bundler/plugins/isolated-styles/split-chunks.js.map +1 -0
  23. package/dist/cli/bundler/plugins/isolated-styles/templates.js +36 -6
  24. package/dist/cli/plugins/content/bundler.d.ts +0 -3
  25. package/dist/cli/plugins/content/bundler.js +4 -20
  26. package/dist/cli/plugins/content/bundler.js.map +1 -1
  27. package/dist/cli/plugins/content/index.js +2 -3
  28. package/dist/cli/plugins/content/index.js.map +1 -1
  29. package/dist/cli/plugins/locale/Locale.js +5 -2
  30. package/dist/cli/plugins/locale/Locale.js.map +1 -1
  31. package/dist/cli/plugins/style/index.d.ts +1 -2
  32. package/dist/cli/plugins/style/index.js +19 -30
  33. package/dist/cli/plugins/style/index.js.map +1 -1
  34. package/dist/cli/resolvers/config.js +1 -2
  35. package/dist/cli/resolvers/config.js.map +1 -1
  36. package/dist/entry/content/adapters/react/Builder.d.ts +4 -2
  37. package/dist/entry/content/adapters/react/Builder.js +11 -5
  38. package/dist/entry/content/adapters/react/Builder.js.map +1 -1
  39. package/dist/entry/content/adapters/react/Node.js +2 -2
  40. package/dist/entry/content/adapters/react/Node.js.map +1 -1
  41. package/dist/entry/content/adapters/react/definition.d.ts +2 -0
  42. package/dist/entry/content/adapters/react/{resolvers/definition.js → definition.js} +1 -1
  43. package/dist/entry/content/adapters/react/definition.js.map +1 -0
  44. package/dist/entry/content/adapters/react/index.d.ts +1 -1
  45. package/dist/entry/content/adapters/react/index.js +1 -1
  46. package/dist/entry/content/adapters/react/index.js.map +1 -1
  47. package/dist/entry/content/adapters/vanilla/Builder.d.ts +4 -2
  48. package/dist/entry/content/adapters/vanilla/Builder.js +14 -5
  49. package/dist/entry/content/adapters/vanilla/Builder.js.map +1 -1
  50. package/dist/entry/content/adapters/vanilla/definition.d.ts +2 -0
  51. package/dist/entry/content/adapters/vanilla/{resolvers/definition.js → definition.js} +2 -2
  52. package/dist/entry/content/adapters/vanilla/definition.js.map +1 -0
  53. package/dist/entry/content/adapters/vanilla/index.d.ts +1 -1
  54. package/dist/entry/content/adapters/vanilla/index.js +1 -1
  55. package/dist/entry/content/adapters/vanilla/index.js.map +1 -1
  56. package/dist/entry/content/adapters/vanilla/utils.d.ts +1 -0
  57. package/dist/entry/content/adapters/vanilla/utils.js +7 -0
  58. package/dist/entry/content/adapters/vanilla/utils.js.map +1 -0
  59. package/dist/entry/content/lifecycle/Builder.d.ts +10 -4
  60. package/dist/entry/content/lifecycle/Builder.js +102 -60
  61. package/dist/entry/content/lifecycle/Builder.js.map +1 -1
  62. package/dist/entry/content/lifecycle/MountBuilder.d.ts +6 -3
  63. package/dist/entry/content/lifecycle/MountBuilder.js +32 -16
  64. package/dist/entry/content/lifecycle/MountBuilder.js.map +1 -1
  65. package/dist/entry/content/lifecycle/context/ContainerRegistry.d.ts +7 -0
  66. package/dist/entry/content/lifecycle/context/ContainerRegistry.js +45 -0
  67. package/dist/entry/content/lifecycle/context/ContainerRegistry.js.map +1 -0
  68. package/dist/entry/content/lifecycle/context/Context.d.ts +6 -3
  69. package/dist/entry/content/lifecycle/context/Context.js +21 -6
  70. package/dist/entry/content/lifecycle/context/Context.js.map +1 -1
  71. package/dist/entry/content/lifecycle/context/ManagedContext.d.ts +4 -1
  72. package/dist/entry/content/lifecycle/context/ManagedContext.js +7 -0
  73. package/dist/entry/content/lifecycle/context/ManagedContext.js.map +1 -1
  74. package/dist/entry/content/lifecycle/context/index.d.ts +1 -0
  75. package/dist/entry/content/lifecycle/context/index.js +6 -4
  76. package/dist/entry/content/lifecycle/context/index.js.map +1 -1
  77. package/dist/entry/content/lifecycle/markers/AttributeMarker.js +3 -1
  78. package/dist/entry/content/lifecycle/markers/AttributeMarker.js.map +1 -1
  79. package/dist/entry/content/lifecycle/nodes/EventNode.d.ts +4 -2
  80. package/dist/entry/content/lifecycle/nodes/EventNode.js +7 -2
  81. package/dist/entry/content/lifecycle/nodes/EventNode.js.map +1 -1
  82. package/dist/entry/content/lifecycle/nodes/FrameNode.d.ts +2 -1
  83. package/dist/entry/content/lifecycle/nodes/FrameNode.js +3 -0
  84. package/dist/entry/content/lifecycle/nodes/FrameNode.js.map +1 -1
  85. package/dist/entry/content/lifecycle/nodes/MarkerNode.d.ts +1 -1
  86. package/dist/entry/content/lifecycle/nodes/MarkerNode.js.map +1 -1
  87. package/dist/entry/content/lifecycle/nodes/MountNode.d.ts +7 -3
  88. package/dist/entry/content/lifecycle/nodes/MountNode.js +47 -12
  89. package/dist/entry/content/lifecycle/nodes/MountNode.js.map +1 -1
  90. package/dist/entry/content/lifecycle/nodes/Node.d.ts +1 -1
  91. package/dist/entry/content/lifecycle/nodes/Node.js.map +1 -1
  92. package/dist/entry/content/lifecycle/nodes/RenderNode.d.ts +13 -4
  93. package/dist/entry/content/lifecycle/nodes/RenderNode.js +71 -6
  94. package/dist/entry/content/lifecycle/nodes/RenderNode.js.map +1 -1
  95. package/dist/entry/content/lifecycle/nodes/ShadowNode.d.ts +2 -1
  96. package/dist/entry/content/lifecycle/nodes/ShadowNode.js +3 -0
  97. package/dist/entry/content/lifecycle/nodes/ShadowNode.js.map +1 -1
  98. package/dist/entry/content/lifecycle/types.d.ts +28 -0
  99. package/dist/entry/content/resolvers/watch.d.ts +1 -1
  100. package/dist/entry/content/resolvers/watch.js +29 -14
  101. package/dist/entry/content/resolvers/watch.js.map +1 -1
  102. package/dist/entry/relay/index.js.map +1 -1
  103. package/dist/shared/locale/index.d.ts +1 -1
  104. package/dist/shared/locale/index.js +3 -1
  105. package/dist/shared/locale/index.js.map +1 -1
  106. package/dist/shared/locale/messages.d.ts +4 -0
  107. package/dist/shared/locale/messages.js +12 -0
  108. package/dist/shared/locale/messages.js.map +1 -1
  109. package/dist/types/content/common.d.ts +8 -0
  110. package/dist/types/content/common.js.map +1 -1
  111. package/dist/types/content/definition.d.ts +5 -0
  112. package/dist/types/locale.d.ts +3 -0
  113. package/dist/types/locale.js.map +1 -1
  114. package/package.json +1 -3
  115. package/types/client.d.ts +3 -3
  116. package/dist/cli/plugins/style/types.d.ts +0 -5
  117. package/dist/entry/content/adapters/react/resolvers/definition.d.ts +0 -2
  118. package/dist/entry/content/adapters/react/resolvers/definition.js.map +0 -1
  119. package/dist/entry/content/adapters/react/resolvers/render.d.ts +0 -2
  120. package/dist/entry/content/adapters/react/resolvers/render.js +0 -9
  121. package/dist/entry/content/adapters/react/resolvers/render.js.map +0 -1
  122. package/dist/entry/content/adapters/vanilla/resolvers/definition.d.ts +0 -2
  123. package/dist/entry/content/adapters/vanilla/resolvers/definition.js.map +0 -1
  124. package/dist/entry/content/adapters/vanilla/resolvers/render.d.ts +0 -3
  125. package/dist/entry/content/adapters/vanilla/resolvers/render.js +0 -15
  126. package/dist/entry/content/adapters/vanilla/resolvers/render.js.map +0 -1
  127. /package/dist/{cli/plugins/style → entry/content/lifecycle}/types.js +0 -0
  128. /package/dist/{cli/plugins/style → entry/content/lifecycle}/types.js.map +0 -0
@@ -1,5 +1,4 @@
1
1
  import { isContentScriptFrameNavigation, resolveContentScriptIsolation } from "./../../../shared/content/index.js";
2
- import AwaitLock from "await-lock";
3
2
  import EntrypointBuilder from "./../../../entry/core/Builder.js";
4
3
  import {
5
4
  createAnchorResolver,
@@ -17,7 +16,7 @@ import {
17
16
  ContentScriptMarker
18
17
  } from "./../../../types/content/index.js";
19
18
  class Builder extends EntrypointBuilder {
20
- lock = new AwaitLock();
19
+ cycle;
21
20
  generation = 0;
22
21
  definition;
23
22
  emitter = new EventEmitter();
@@ -27,27 +26,15 @@ class Builder extends EntrypointBuilder {
27
26
  constructor(input) {
28
27
  super();
29
28
  const definition = input;
30
- const isolation = resolveContentScriptIsolation(definition.isolation, "render" in definition);
31
- if (definition.boundary !== void 0) {
32
- if (typeof definition.boundary !== "function") {
33
- throw new Error("Content script boundary must be a synchronous setup handler");
34
- }
35
- if (isolation.type === "none") {
36
- throw new Error("Content script boundary requires Shadow DOM or an iframe");
37
- }
38
- }
39
- if (definition.target !== void 0 && (isolation.type === "none" || isContentScriptFrameNavigation(isolation))) {
40
- throw new Error("Content script target requires Shadow DOM or an iframe with local rendering");
41
- }
42
29
  this.definition = {
43
30
  ...definition,
44
31
  marker: this.resolveMarker(definition.marker),
45
32
  anchor: this.resolveAnchor(definition.anchor),
46
33
  mount: this.resolveMount(definition.mount),
47
34
  container: this.resolveContainer(definition.container),
48
- target: createTargetResolver(definition.target),
49
- render: definition.render === true ? true : this.resolveRender(definition.render),
50
- isolation,
35
+ target: this.resolveTarget(definition.target),
36
+ isolation: this.resolveIsolation(definition),
37
+ render: this.resolveRender(definition.render),
51
38
  watch: this.resolveWatch(definition.watch)
52
39
  };
53
40
  }
@@ -80,11 +67,29 @@ class Builder extends EntrypointBuilder {
80
67
  resolveContainer(container) {
81
68
  return createContainerResolver(container);
82
69
  }
70
+ resolveTarget(target) {
71
+ return createTargetResolver(target);
72
+ }
73
+ resolveIsolation(definition) {
74
+ const isolation = resolveContentScriptIsolation(definition.isolation, "render" in definition);
75
+ if (definition.boundary !== void 0) {
76
+ if (typeof definition.boundary !== "function") {
77
+ throw new Error("Content script boundary must be a synchronous setup handler");
78
+ }
79
+ if (isolation.type === "none") {
80
+ throw new Error("Content script boundary requires Shadow DOM or an iframe");
81
+ }
82
+ }
83
+ if (definition.target !== void 0 && (isolation.type === "none" || isContentScriptFrameNavigation(isolation))) {
84
+ throw new Error("Content script target requires Shadow DOM or an iframe with local rendering");
85
+ }
86
+ return isolation;
87
+ }
83
88
  resolveRender(render) {
84
- if (render !== void 0) {
85
- throw new Error("Content script rendering requires a renderer adapter");
89
+ if (render === true || render === void 0) {
90
+ return render;
86
91
  }
87
- return void 0;
92
+ throw new Error("Content script rendering requires a renderer adapter");
88
93
  }
89
94
  resolveWatch(watch) {
90
95
  if (watch === void 0) {
@@ -105,42 +110,38 @@ class Builder extends EntrypointBuilder {
105
110
  return;
106
111
  }
107
112
  const { render, prepare, main, anchor, marker, container, boundary, target, watch, mount, ...options } = this.definition;
108
- const resolvedMarker = await marker(options);
109
- if (generation !== this.generation) {
110
- return;
111
- }
112
- this.marker = resolvedMarker;
113
113
  await (main == null ? void 0 : main(this.context, options));
114
114
  if (generation !== this.generation) {
115
115
  return;
116
116
  }
117
117
  if (render !== void 0 || prepare !== void 0 || isContentScriptFrameNavigation(this.definition.isolation)) {
118
- await this.processing(generation);
118
+ const resolvedMarker = await marker(options);
119
119
  if (generation !== this.generation) {
120
120
  return;
121
121
  }
122
- this.unwatch = watch(async () => {
123
- if (generation !== this.generation) {
124
- return;
125
- }
126
- try {
127
- this.context.mount();
128
- await this.processing(generation);
129
- } catch (error) {
130
- console.error("Content script processing on watch error", error);
131
- }
132
- }, this.context);
122
+ this.marker = resolvedMarker;
123
+ await this.requestProcessing(generation);
124
+ if (generation !== this.generation) {
125
+ return;
126
+ }
127
+ const onError = (error) => {
128
+ console.error("Content script processing on watch error", error);
129
+ };
130
+ this.unwatch = watch(() => this.requestProcessing(generation, onError), this.context);
133
131
  }
134
132
  }
135
133
  async destroy() {
136
134
  var _a;
137
135
  this.generation++;
138
- this.lock = new AwaitLock();
136
+ this.cycle = void 0;
139
137
  (_a = this.unwatch) == null ? void 0 : _a.call(this);
140
138
  this.unwatch = void 0;
141
- this.context.clear();
142
- this.context.unwatch();
143
- this.marker.reset();
139
+ try {
140
+ this.context.clear();
141
+ } finally {
142
+ this.context.unwatch();
143
+ this.marker.reset();
144
+ }
144
145
  }
145
146
  getPrepareProps(anchor) {
146
147
  const {
@@ -158,46 +159,75 @@ class Builder extends EntrypointBuilder {
158
159
  } = this.definition;
159
160
  return { ...options, anchor };
160
161
  }
161
- async processing(generation) {
162
- const lock = this.lock;
163
- await lock.acquireAsync();
162
+ requestProcessing(generation, onError) {
163
+ var _a;
164
+ if (generation !== this.generation) {
165
+ return Promise.resolve();
166
+ }
167
+ if (((_a = this.cycle) == null ? void 0 : _a.generation) === generation) {
168
+ this.cycle.pending = true;
169
+ return this.cycle.promise;
170
+ }
171
+ const cycle = {
172
+ generation,
173
+ pending: true,
174
+ promise: Promise.resolve().then(() => this.drainProcessing(cycle))
175
+ };
176
+ if (onError) {
177
+ cycle.promise = cycle.promise.catch(onError);
178
+ }
179
+ this.cycle = cycle;
180
+ return cycle.promise;
181
+ }
182
+ async drainProcessing(cycle) {
164
183
  try {
165
- if (generation !== this.generation) {
166
- return;
167
- }
168
- const anchor = await this.definition.anchor();
169
- if (generation !== this.generation) {
170
- return;
171
- }
172
- const anchors = this.marker.for(anchor).unmarked().filter((anchor2) => anchor2.isConnected);
173
- const results = await Promise.allSettled(anchors.map((anchor2) => this.processAnchor(anchor2, generation)));
174
- const errors = results.flatMap((result) => result.status === "rejected" ? [result.reason] : []);
175
- if (errors.length && generation === this.generation) {
176
- console.error(new AggregateError(errors, "Content script anchor processing failed"));
184
+ while (cycle.pending && cycle.generation === this.generation) {
185
+ cycle.pending = false;
186
+ this.context.mount();
187
+ if (cycle.generation !== this.generation) {
188
+ return;
189
+ }
190
+ await this.processing(cycle.generation);
177
191
  }
178
192
  } finally {
179
- lock.release();
193
+ if (this.cycle === cycle) {
194
+ this.cycle = void 0;
195
+ }
196
+ }
197
+ }
198
+ async processing(generation) {
199
+ const anchor = await this.definition.anchor();
200
+ if (generation !== this.generation) {
201
+ return;
202
+ }
203
+ const anchors = this.marker.for(anchor).unmarked().filter((anchor2) => anchor2.isConnected);
204
+ const results = await Promise.allSettled(anchors.map((anchor2) => this.processAnchor(anchor2, generation)));
205
+ const errors = results.flatMap((result) => result.status === "rejected" ? [result.reason] : []);
206
+ if (errors.length && generation === this.generation) {
207
+ console.error(new AggregateError(errors, "Content script anchor processing failed"));
180
208
  }
181
209
  }
182
210
  async processAnchor(anchor, generation) {
183
- var _a, _b, _c;
211
+ var _a, _b, _c, _d;
184
212
  const current = () => generation === this.generation && anchor.isConnected;
185
213
  const data = await ((_b = (_a = this.definition).prepare) == null ? void 0 : _b.call(_a, this.getPrepareProps(anchor)));
186
214
  if (!current()) {
187
215
  return;
188
216
  }
189
- const node = new EventNode(await this.createNode(anchor, data, data !== false), this.emitter);
217
+ const assembly = await this.createNode(anchor, data);
218
+ const node = new EventNode(assembly.node, this.emitter, assembly.renderer);
190
219
  if (!current()) {
191
220
  node.unmount();
192
221
  return;
193
222
  }
223
+ (_c = assembly.renderer) == null ? void 0 : _c.setErrorHandler((error) => this.handleRenderError(node, error, generation));
194
224
  this.context.add(node);
195
225
  if (generation !== this.generation) {
196
226
  return;
197
227
  }
198
228
  try {
199
229
  node.mount();
200
- if (!current() && !((_c = node.container) == null ? void 0 : _c.isConnected)) {
230
+ if (!current() && !((_d = node.container) == null ? void 0 : _d.isConnected)) {
201
231
  this.context.remove(node);
202
232
  }
203
233
  } catch (error) {
@@ -205,6 +235,18 @@ class Builder extends EntrypointBuilder {
205
235
  throw error;
206
236
  }
207
237
  }
238
+ handleRenderError(node, error, generation) {
239
+ if (generation !== this.generation) {
240
+ return;
241
+ }
242
+ const errors = [error];
243
+ try {
244
+ this.context.remove(node);
245
+ } catch (cause) {
246
+ errors.push(cause);
247
+ }
248
+ console.error(new AggregateError(errors, "Content script deferred mount failed"));
249
+ }
208
250
  }
209
251
  export {
210
252
  Builder as default
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/entry/content/lifecycle/Builder.ts"],"sourcesContent":["import {isContentScriptFrameNavigation, resolveContentScriptIsolation} from \"@shared/content\";\nimport AwaitLock from \"await-lock\";\n\nimport EntrypointBuilder from \"@entry/core/Builder\";\n\nimport {\n createAnchorResolver,\n createAwaitFirstStrategy,\n createContainerResolver,\n createTargetResolver,\n withLocationTracking,\n createAppendMountHandler,\n createMutationObserverStrategy,\n} from \"../resolvers\";\n\nimport {ManagedContext, EventEmitter} from \"./context\";\nimport {AttributeMarker, WeakMarker} from \"./markers\";\nimport {EventNode} from \"./nodes\";\n\nimport {\n ContentScriptAnchor,\n ContentScriptAnchorGetter,\n ContentScriptBuilder,\n ContentScriptContainerCreator,\n ContentScriptContainerFactory,\n ContentScriptContainerOptions,\n ContentScriptContainerTag,\n ContentScriptContext,\n ContentScriptDefinition,\n ContentScriptIsolation,\n ContentScriptMarker,\n ContentScriptMarkerContract,\n ContentScriptMarkerGetter,\n ContentScriptMarkerResolver,\n ContentScriptMarkerType,\n ContentScriptMountFunction,\n ContentScriptNode,\n ContentScriptPrepareProps,\n ContentScriptOptions,\n ContentScriptRenderHandler,\n ContentScriptRenderValue,\n ContentScriptResolvedDefinition,\n ContentScriptWatchStrategy,\n} from \"@typing/content\";\n\nexport default abstract class Builder<\n Data = unknown,\n Isolation extends `${ContentScriptIsolation}` = `${ContentScriptIsolation}`,\n>\n extends EntrypointBuilder\n implements ContentScriptBuilder\n{\n private lock = new AwaitLock();\n\n protected generation = 0;\n\n protected readonly definition: ContentScriptResolvedDefinition<Data>;\n\n protected readonly emitter = new EventEmitter();\n\n protected readonly context = new ManagedContext(this.emitter);\n\n protected marker: ContentScriptMarkerContract = new AttributeMarker();\n\n protected unwatch?: () => void;\n\n protected abstract createNode(anchor: Element, data: Data, enabled: boolean): Promise<ContentScriptNode>;\n\n protected constructor(input: ContentScriptDefinition<Data, Isolation>) {\n super();\n\n // Normalization selects the isolation at runtime; its node supplies the matching callback props.\n const definition = input as ContentScriptDefinition<Data>;\n const isolation = resolveContentScriptIsolation(definition.isolation, \"render\" in definition);\n\n if (definition.boundary !== undefined) {\n if (typeof definition.boundary !== \"function\") {\n throw new Error(\"Content script boundary must be a synchronous setup handler\");\n }\n\n if (isolation.type === \"none\") {\n throw new Error(\"Content script boundary requires Shadow DOM or an iframe\");\n }\n }\n\n if (\n definition.target !== undefined &&\n (isolation.type === \"none\" || isContentScriptFrameNavigation(isolation))\n ) {\n throw new Error(\"Content script target requires Shadow DOM or an iframe with local rendering\");\n }\n\n this.definition = {\n ...definition,\n marker: this.resolveMarker(definition.marker),\n anchor: this.resolveAnchor(definition.anchor),\n mount: this.resolveMount(definition.mount),\n container: this.resolveContainer(definition.container),\n target: createTargetResolver(definition.target),\n render: definition.render === true ? true : this.resolveRender(definition.render),\n isolation,\n watch: this.resolveWatch(definition.watch),\n };\n }\n\n protected resolveMarker(marker: ContentScriptMarkerType | ContentScriptMarkerGetter): ContentScriptMarkerResolver {\n return async (options: ContentScriptOptions) => {\n if (typeof marker === \"function\") {\n marker = await marker(options);\n }\n\n if (!marker) {\n marker = ContentScriptMarker.Attribute;\n }\n\n if (typeof marker === \"string\") {\n switch (marker) {\n case ContentScriptMarker.Weak:\n return new WeakMarker();\n\n case ContentScriptMarker.Attribute:\n default:\n return new AttributeMarker();\n }\n }\n\n return marker;\n };\n }\n\n protected resolveAnchor(anchor?: ContentScriptAnchor | ContentScriptAnchorGetter): ContentScriptAnchorGetter {\n return createAnchorResolver(anchor);\n }\n\n protected resolveMount(mount?: ContentScriptMountFunction): ContentScriptMountFunction {\n return mount || createAppendMountHandler();\n }\n\n protected resolveContainer(\n container?: ContentScriptContainerTag | ContentScriptContainerOptions | ContentScriptContainerFactory<Data>\n ): ContentScriptContainerCreator<Data> {\n return createContainerResolver(container);\n }\n\n protected resolveRender(\n render?: ContentScriptRenderValue<Data> | ContentScriptRenderHandler<Data>\n ): ContentScriptRenderHandler<Data> | undefined {\n if (render !== undefined) {\n throw new Error(\"Content script rendering requires a renderer adapter\");\n }\n\n return undefined;\n }\n\n protected resolveWatch(watch?: true | ContentScriptWatchStrategy): ContentScriptWatchStrategy {\n if (watch === undefined) {\n watch = createAwaitFirstStrategy();\n } else if (watch === true) {\n watch = createMutationObserverStrategy();\n }\n\n return withLocationTracking(watch);\n }\n\n public getContext(): ContentScriptContext {\n return this.context;\n }\n\n public async build(): Promise<void> {\n const destroying = this.destroy();\n const generation = this.generation;\n await destroying;\n\n if (generation !== this.generation) {\n return;\n }\n\n const {render, prepare, main, anchor, marker, container, boundary, target, watch, mount, ...options} =\n this.definition;\n\n const resolvedMarker = await marker(options);\n\n if (generation !== this.generation) {\n return;\n }\n\n this.marker = resolvedMarker;\n\n await main?.(this.context, options);\n\n if (generation !== this.generation) {\n return;\n }\n\n if (\n render !== undefined ||\n prepare !== undefined ||\n isContentScriptFrameNavigation(this.definition.isolation)\n ) {\n await this.processing(generation);\n\n if (generation !== this.generation) {\n return;\n }\n\n this.unwatch = watch(async () => {\n if (generation !== this.generation) {\n return;\n }\n\n try {\n this.context.mount();\n await this.processing(generation);\n } catch (error) {\n console.error(\"Content script processing on watch error\", error);\n }\n }, this.context);\n }\n }\n\n public async destroy(): Promise<void> {\n this.generation++;\n this.lock = new AwaitLock();\n\n this.unwatch?.();\n this.unwatch = undefined;\n\n this.context.clear();\n this.context.unwatch();\n this.marker.reset();\n }\n\n protected getPrepareProps(anchor: Element): ContentScriptPrepareProps {\n const {\n anchor: _,\n marker,\n mount,\n watch,\n prepare,\n render,\n container,\n boundary,\n target,\n main,\n ...options\n } = this.definition;\n\n return {...options, anchor};\n }\n\n protected async processing(generation: number): Promise<void> {\n const lock = this.lock;\n await lock.acquireAsync();\n\n try {\n if (generation !== this.generation) {\n return;\n }\n\n const anchor = await this.definition.anchor();\n\n if (generation !== this.generation) {\n return;\n }\n\n const anchors = this.marker\n .for(anchor)\n .unmarked()\n .filter(anchor => anchor.isConnected);\n\n const results = await Promise.allSettled(anchors.map(anchor => this.processAnchor(anchor, generation)));\n const errors = results.flatMap(result => (result.status === \"rejected\" ? [result.reason] : []));\n\n if (errors.length && generation === this.generation) {\n console.error(new AggregateError(errors, \"Content script anchor processing failed\"));\n }\n } finally {\n lock.release();\n }\n }\n\n protected async processAnchor(anchor: Element, generation: number): Promise<void> {\n const current = () => generation === this.generation && anchor.isConnected;\n const data = await this.definition.prepare?.(this.getPrepareProps(anchor));\n\n if (!current()) {\n return;\n }\n\n const node = new EventNode(await this.createNode(anchor, data as Data, data !== false), this.emitter);\n\n if (!current()) {\n node.unmount();\n\n return;\n }\n\n this.context.add(node);\n\n if (generation !== this.generation) {\n return;\n }\n\n try {\n node.mount();\n\n if (!current() && !node.container?.isConnected) {\n this.context.remove(node);\n }\n } catch (error) {\n this.context.remove(node);\n throw error;\n }\n }\n}\n"],"mappings":"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","names":["anchor"]}
1
+ {"version":3,"sources":["../../../../src/entry/content/lifecycle/Builder.ts"],"sourcesContent":["import {isContentScriptFrameNavigation, resolveContentScriptIsolation} from \"@shared/content\";\n\nimport EntrypointBuilder from \"@entry/core/Builder\";\n\nimport {\n createAnchorResolver,\n createAwaitFirstStrategy,\n createContainerResolver,\n createTargetResolver,\n withLocationTracking,\n createAppendMountHandler,\n createMutationObserverStrategy,\n} from \"../resolvers\";\n\nimport {ManagedContext, EventEmitter} from \"./context\";\nimport {AttributeMarker, WeakMarker} from \"./markers\";\nimport {EventNode} from \"./nodes\";\n\nimport type {ContentScriptNodeAssembly, ContentScriptCycle} from \"./types\";\n\nimport {\n ContentScriptNode,\n ContentScriptAnchor,\n ContentScriptAnchorGetter,\n ContentScriptBuilder,\n ContentScriptContainerCreator,\n ContentScriptContainerFactory,\n ContentScriptContainerOptions,\n ContentScriptContainerTag,\n ContentScriptContext,\n ContentScriptDefinition,\n ContentScriptIsolation,\n ContentScriptIsolationOptions,\n ContentScriptMarker,\n ContentScriptMarkerContract,\n ContentScriptMarkerGetter,\n ContentScriptMarkerResolver,\n ContentScriptMarkerType,\n ContentScriptMountFunction,\n ContentScriptPrepareProps,\n ContentScriptPrepareResult,\n ContentScriptOptions,\n ContentScriptRenderHandler,\n ContentScriptRenderValue,\n ContentScriptResolvedDefinition,\n ContentScriptTarget,\n ContentScriptTargetCreator,\n ContentScriptWatchStrategy,\n} from \"@typing/content\";\n\nexport default abstract class Builder<\n Data = unknown,\n Isolation extends `${ContentScriptIsolation}` = `${ContentScriptIsolation}`,\n>\n extends EntrypointBuilder\n implements ContentScriptBuilder\n{\n private cycle?: ContentScriptCycle;\n\n protected generation = 0;\n\n protected readonly definition: ContentScriptResolvedDefinition<Data>;\n\n protected readonly emitter = new EventEmitter();\n\n protected readonly context = new ManagedContext(this.emitter);\n\n protected marker: ContentScriptMarkerContract = new AttributeMarker();\n\n protected unwatch?: () => void;\n\n protected abstract createNode(\n anchor: Element,\n result: ContentScriptPrepareResult<Data> | undefined\n ): Promise<ContentScriptNodeAssembly>;\n\n protected constructor(input: ContentScriptDefinition<Data, Isolation>) {\n super();\n\n // Normalization selects the isolation at runtime; its node supplies the matching callback props.\n const definition = input as ContentScriptDefinition<Data>;\n\n this.definition = {\n ...definition,\n marker: this.resolveMarker(definition.marker),\n anchor: this.resolveAnchor(definition.anchor),\n mount: this.resolveMount(definition.mount),\n container: this.resolveContainer(definition.container),\n target: this.resolveTarget(definition.target),\n isolation: this.resolveIsolation(definition),\n render: this.resolveRender(definition.render),\n watch: this.resolveWatch(definition.watch),\n };\n }\n\n protected resolveMarker(marker: ContentScriptMarkerType | ContentScriptMarkerGetter): ContentScriptMarkerResolver {\n return async (options: ContentScriptOptions) => {\n if (typeof marker === \"function\") {\n marker = await marker(options);\n }\n\n if (!marker) {\n marker = ContentScriptMarker.Attribute;\n }\n\n if (typeof marker === \"string\") {\n switch (marker) {\n case ContentScriptMarker.Weak:\n return new WeakMarker();\n\n case ContentScriptMarker.Attribute:\n default:\n return new AttributeMarker();\n }\n }\n\n return marker;\n };\n }\n\n protected resolveAnchor(anchor?: ContentScriptAnchor | ContentScriptAnchorGetter): ContentScriptAnchorGetter {\n return createAnchorResolver(anchor);\n }\n\n protected resolveMount(mount?: ContentScriptMountFunction): ContentScriptMountFunction {\n return mount || createAppendMountHandler();\n }\n\n protected resolveContainer(\n container?: ContentScriptContainerTag | ContentScriptContainerOptions | ContentScriptContainerFactory<Data>\n ): ContentScriptContainerCreator<Data> {\n return createContainerResolver(container);\n }\n\n protected resolveTarget(target?: ContentScriptTarget<Data>): ContentScriptTargetCreator<Data> {\n return createTargetResolver(target);\n }\n\n protected resolveIsolation(definition: ContentScriptDefinition<Data>): ContentScriptIsolationOptions {\n const isolation = resolveContentScriptIsolation(definition.isolation, \"render\" in definition);\n\n if (definition.boundary !== undefined) {\n if (typeof definition.boundary !== \"function\") {\n throw new Error(\"Content script boundary must be a synchronous setup handler\");\n }\n\n if (isolation.type === \"none\") {\n throw new Error(\"Content script boundary requires Shadow DOM or an iframe\");\n }\n }\n\n if (\n definition.target !== undefined &&\n (isolation.type === \"none\" || isContentScriptFrameNavigation(isolation))\n ) {\n throw new Error(\"Content script target requires Shadow DOM or an iframe with local rendering\");\n }\n\n return isolation;\n }\n\n protected resolveRender(\n render?: ContentScriptRenderValue<Data> | ContentScriptRenderHandler<Data>\n ): true | ContentScriptRenderHandler<Data> | undefined {\n if (render === true || render === undefined) {\n return render;\n }\n\n throw new Error(\"Content script rendering requires a renderer adapter\");\n }\n\n protected resolveWatch(watch?: true | ContentScriptWatchStrategy): ContentScriptWatchStrategy {\n if (watch === undefined) {\n watch = createAwaitFirstStrategy();\n } else if (watch === true) {\n watch = createMutationObserverStrategy();\n }\n\n return withLocationTracking(watch);\n }\n\n public getContext(): ContentScriptContext {\n return this.context;\n }\n\n public async build(): Promise<void> {\n const destroying = this.destroy();\n const generation = this.generation;\n await destroying;\n\n if (generation !== this.generation) {\n return;\n }\n\n const {render, prepare, main, anchor, marker, container, boundary, target, watch, mount, ...options} =\n this.definition;\n\n await main?.(this.context, options);\n\n if (generation !== this.generation) {\n return;\n }\n\n if (\n render !== undefined ||\n prepare !== undefined ||\n isContentScriptFrameNavigation(this.definition.isolation)\n ) {\n const resolvedMarker = await marker(options);\n\n if (generation !== this.generation) {\n return;\n }\n\n this.marker = resolvedMarker;\n\n await this.requestProcessing(generation);\n\n if (generation !== this.generation) {\n return;\n }\n\n const onError = (error: unknown): void => {\n console.error(\"Content script processing on watch error\", error);\n };\n\n this.unwatch = watch(() => this.requestProcessing(generation, onError), this.context);\n }\n }\n\n public async destroy(): Promise<void> {\n this.generation++;\n this.cycle = undefined;\n\n this.unwatch?.();\n this.unwatch = undefined;\n\n try {\n this.context.clear();\n } finally {\n this.context.unwatch();\n this.marker.reset();\n }\n }\n\n protected getPrepareProps(anchor: Element): ContentScriptPrepareProps {\n const {\n anchor: _,\n marker,\n mount,\n watch,\n prepare,\n render,\n container,\n boundary,\n target,\n main,\n ...options\n } = this.definition;\n\n return {...options, anchor};\n }\n\n private requestProcessing(generation: number, onError?: (error: unknown) => void): Promise<void> {\n if (generation !== this.generation) {\n return Promise.resolve();\n }\n\n if (this.cycle?.generation === generation) {\n this.cycle.pending = true;\n\n return this.cycle.promise;\n }\n\n const cycle: ContentScriptCycle = {\n generation,\n pending: true,\n promise: Promise.resolve().then(() => this.drainProcessing(cycle)),\n };\n\n if (onError) {\n // One handler per cycle, not one suspended async callback per watch notification.\n cycle.promise = cycle.promise.catch(onError);\n }\n\n this.cycle = cycle;\n\n return cycle.promise;\n }\n\n private async drainProcessing(cycle: ContentScriptCycle): Promise<void> {\n try {\n while (cycle.pending && cycle.generation === this.generation) {\n cycle.pending = false;\n this.context.mount();\n\n if (cycle.generation !== this.generation) {\n return;\n }\n\n await this.processing(cycle.generation);\n }\n } finally {\n if (this.cycle === cycle) {\n this.cycle = undefined;\n }\n }\n }\n\n protected async processing(generation: number): Promise<void> {\n const anchor = await this.definition.anchor();\n\n if (generation !== this.generation) {\n return;\n }\n\n const anchors = this.marker\n .for(anchor)\n .unmarked()\n .filter(anchor => anchor.isConnected);\n\n const results = await Promise.allSettled(anchors.map(anchor => this.processAnchor(anchor, generation)));\n const errors = results.flatMap(result => (result.status === \"rejected\" ? [result.reason] : []));\n\n if (errors.length && generation === this.generation) {\n console.error(new AggregateError(errors, \"Content script anchor processing failed\"));\n }\n }\n\n protected async processAnchor(anchor: Element, generation: number): Promise<void> {\n const current = () => generation === this.generation && anchor.isConnected;\n const data = await this.definition.prepare?.(this.getPrepareProps(anchor));\n\n if (!current()) {\n return;\n }\n\n const assembly = await this.createNode(anchor, data);\n const node = new EventNode(assembly.node, this.emitter, assembly.renderer);\n\n if (!current()) {\n node.unmount();\n\n return;\n }\n\n // Add listeners can mount immediately, so connect the renderer before publishing the node.\n assembly.renderer?.setErrorHandler(error => this.handleRenderError(node, error, generation));\n this.context.add(node);\n\n if (generation !== this.generation) {\n return;\n }\n\n try {\n node.mount();\n\n if (!current() && !node.container?.isConnected) {\n this.context.remove(node);\n }\n } catch (error) {\n this.context.remove(node);\n throw error;\n }\n }\n\n private handleRenderError(node: ContentScriptNode, error: unknown, generation: number): void {\n if (generation !== this.generation) {\n return;\n }\n\n const errors = [error];\n\n try {\n this.context.remove(node);\n } catch (cause) {\n errors.push(cause);\n }\n\n console.error(new AggregateError(errors, \"Content script deferred mount failed\"));\n }\n}\n"],"mappings":"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","names":["anchor"]}
@@ -1,8 +1,11 @@
1
1
  import Builder from "./Builder.js";
2
- import { ContentScriptDefinition, ContentScriptIsolation, ContentScriptNode, ContentScriptProps, ContentScriptRenderHandler } from "../../../types/content/index.js";
2
+ import type { ContentScriptIsolationAssembly, ContentScriptNodeAssembly, ContentScriptRenderLifecycle, ContentScriptRenderOptions } from "./types.js";
3
+ import { ContentScriptDefinition, ContentScriptIsolation, ContentScriptNode, ContentScriptPrepareResult, ContentScriptProps, ContentScriptRenderHandler } from "../../../types/content/index.js";
3
4
  export default class MountBuilder<Data = unknown, Isolation extends `${ContentScriptIsolation}` = `${ContentScriptIsolation}`> extends Builder<Data, Isolation> {
4
5
  constructor(definition: ContentScriptDefinition<Data, Isolation>);
5
6
  protected getProps(node: ContentScriptNode, data: Data): ContentScriptProps<Data>;
6
- protected createNode(anchor: Element, data: Data, enabled: boolean): Promise<ContentScriptNode>;
7
- protected createRenderer(node: ContentScriptNode, render: ContentScriptRenderHandler<Data>, props: () => ContentScriptProps<Data>): ContentScriptNode;
7
+ protected createNode(anchor: Element, result: ContentScriptPrepareResult<Data> | undefined): Promise<ContentScriptNodeAssembly>;
8
+ protected createMountNode(anchor: Element, data: Data): Promise<ContentScriptNode>;
9
+ protected createIsolation(node: ContentScriptNode, data: Data): ContentScriptIsolationAssembly;
10
+ protected createRenderer(node: ContentScriptNode, render: ContentScriptRenderHandler<Data>, props: () => ContentScriptProps<Data>, options: ContentScriptRenderOptions): ContentScriptNode & ContentScriptRenderLifecycle;
8
11
  }
@@ -21,33 +21,49 @@ class MountBuilder extends Builder {
21
21
  boundary: node.boundary
22
22
  };
23
23
  }
24
- async createNode(anchor, data, enabled) {
24
+ async createNode(anchor, result) {
25
25
  const navigation = isContentScriptFrameNavigation(this.definition.isolation);
26
26
  const render = this.definition.render;
27
- if (!enabled || !navigation && (render === void 0 || render === true)) {
28
- return new MarkerNode(new Node(anchor), this.marker);
27
+ if (result === false || !navigation && (render === void 0 || render === true)) {
28
+ return { node: new MarkerNode(new Node(anchor), this.marker) };
29
29
  }
30
+ const data = result;
31
+ const mountedNode = await this.createMountNode(anchor, data);
32
+ const { node, ready } = this.createIsolation(mountedNode, data);
33
+ if (navigation || typeof render !== "function") {
34
+ return { node };
35
+ }
36
+ const renderer = this.createRenderer(node, render, () => this.getProps(node, data), { ready });
37
+ return { node: renderer, renderer };
38
+ }
39
+ async createMountNode(anchor, data) {
30
40
  const marker = this.marker;
31
41
  const container = await this.definition.container({ ...this.getPrepareProps(anchor), data });
32
- const mountedNode = new MountNode(new MarkerNode(new Node(anchor, container), marker), this.definition.mount);
42
+ return new MountNode(
43
+ new MarkerNode(new Node(anchor, container), marker),
44
+ this.context.containers,
45
+ this.definition.mount
46
+ );
47
+ }
48
+ createIsolation(node, data) {
49
+ const options = this.definition.isolation;
50
+ if (options.type === ContentScriptIsolation.None) {
51
+ return { node };
52
+ }
33
53
  const setup = new IsolationSetup({
34
- props: () => ({ ...this.getPrepareProps(anchor), data }),
35
- container: () => mountedNode.container,
54
+ props: () => ({ ...this.getPrepareProps(node.anchor), data }),
55
+ container: () => node.container,
36
56
  boundary: this.definition.boundary,
37
57
  target: this.definition.target
38
58
  });
39
- let node = mountedNode;
40
- switch (this.definition.isolation.type) {
41
- case ContentScriptIsolation.Shadow:
42
- node = new ShadowNode(mountedNode, this.definition.isolation, setup);
43
- break;
44
- case ContentScriptIsolation.Iframe:
45
- node = new FrameNode(mountedNode, this.definition.isolation, () => this.context.mount(), setup);
46
- break;
59
+ if (options.type === ContentScriptIsolation.Shadow) {
60
+ const shadow = new ShadowNode(node, options, setup);
61
+ return { node: shadow, ready: () => shadow.ready() };
47
62
  }
48
- return navigation || typeof render !== "function" ? node : this.createRenderer(node, render, () => this.getProps(node, data));
63
+ const frame = new FrameNode(node, options, () => this.context.mount(), setup);
64
+ return { node: frame, ready: () => frame.ready() };
49
65
  }
50
- createRenderer(node, render, props) {
66
+ createRenderer(node, render, props, options) {
51
67
  throw new Error("Content script rendering requires a renderer adapter");
52
68
  }
53
69
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/entry/content/lifecycle/MountBuilder.ts"],"sourcesContent":["import Builder from \"./Builder\";\nimport IsolationSetup from \"./IsolationSetup\";\nimport {FrameNode, MountNode, MarkerNode, ShadowNode, Node} from \"./nodes\";\nimport {isContentScriptFrameNavigation} from \"@shared/content\";\n\nimport {\n ContentScriptDefinition,\n ContentScriptIsolation,\n ContentScriptNode,\n ContentScriptProps,\n ContentScriptRenderHandler,\n} from \"@typing/content\";\n\nexport default class MountBuilder<\n Data = unknown,\n Isolation extends `${ContentScriptIsolation}` = `${ContentScriptIsolation}`,\n> extends Builder<Data, Isolation> {\n public constructor(definition: ContentScriptDefinition<Data, Isolation>) {\n super(definition);\n }\n\n protected getProps(node: ContentScriptNode, data: Data): ContentScriptProps<Data> {\n if (!node.container || !node.target) {\n throw new Error(\"Content script render requires a container and target\");\n }\n\n return {\n ...this.getPrepareProps(node.anchor),\n data,\n container: node.container,\n target: node.target,\n boundary: node.boundary,\n };\n }\n\n protected async createNode(anchor: Element, data: Data, enabled: boolean): Promise<ContentScriptNode> {\n const navigation = isContentScriptFrameNavigation(this.definition.isolation);\n const render = this.definition.render;\n\n if (!enabled || (!navigation && (render === undefined || render === true))) {\n return new MarkerNode(new Node(anchor), this.marker);\n }\n\n const marker = this.marker;\n const container = await this.definition.container({...this.getPrepareProps(anchor), data});\n\n const mountedNode = new MountNode(new MarkerNode(new Node(anchor, container), marker), this.definition.mount);\n\n const setup = new IsolationSetup({\n props: () => ({...this.getPrepareProps(anchor), data}),\n container: () => mountedNode.container,\n boundary: this.definition.boundary,\n target: this.definition.target,\n });\n\n let node: ContentScriptNode = mountedNode;\n\n switch (this.definition.isolation.type) {\n case ContentScriptIsolation.Shadow:\n node = new ShadowNode(mountedNode, this.definition.isolation, setup);\n break;\n case ContentScriptIsolation.Iframe:\n node = new FrameNode(mountedNode, this.definition.isolation, () => this.context.mount(), setup);\n break;\n }\n\n return navigation || typeof render !== \"function\"\n ? node\n : this.createRenderer(node, render, () => this.getProps(node, data));\n }\n\n protected createRenderer(\n node: ContentScriptNode,\n render: ContentScriptRenderHandler<Data>,\n props: () => ContentScriptProps<Data>\n ): ContentScriptNode {\n throw new Error(\"Content script rendering requires a renderer adapter\");\n }\n}\n"],"mappings":"AAAA,OAAO,aAAa;AACpB,OAAO,oBAAoB;AAC3B,SAAQ,WAAW,WAAW,YAAY,YAAY,YAAW;AACjE,SAAQ,sCAAqC;AAE7C;AAAA,EAEI;AAAA,OAIG;AAEP,MAAO,qBAGG,QAAyB;AAAA,EACxB,YAAY,YAAsD;AACrE,UAAM,UAAU;AAAA,EACpB;AAAA,EAEU,SAAS,MAAyB,MAAsC;AAC9E,QAAI,CAAC,KAAK,aAAa,CAAC,KAAK,QAAQ;AACjC,YAAM,IAAI,MAAM,uDAAuD;AAAA,IAC3E;AAEA,WAAO;AAAA,MACH,GAAG,KAAK,gBAAgB,KAAK,MAAM;AAAA,MACnC;AAAA,MACA,WAAW,KAAK;AAAA,MAChB,QAAQ,KAAK;AAAA,MACb,UAAU,KAAK;AAAA,IACnB;AAAA,EACJ;AAAA,EAEA,MAAgB,WAAW,QAAiB,MAAY,SAA8C;AAClG,UAAM,aAAa,+BAA+B,KAAK,WAAW,SAAS;AAC3E,UAAM,SAAS,KAAK,WAAW;AAE/B,QAAI,CAAC,WAAY,CAAC,eAAe,WAAW,UAAa,WAAW,OAAQ;AACxE,aAAO,IAAI,WAAW,IAAI,KAAK,MAAM,GAAG,KAAK,MAAM;AAAA,IACvD;AAEA,UAAM,SAAS,KAAK;AACpB,UAAM,YAAY,MAAM,KAAK,WAAW,UAAU,EAAC,GAAG,KAAK,gBAAgB,MAAM,GAAG,KAAI,CAAC;AAEzF,UAAM,cAAc,IAAI,UAAU,IAAI,WAAW,IAAI,KAAK,QAAQ,SAAS,GAAG,MAAM,GAAG,KAAK,WAAW,KAAK;AAE5G,UAAM,QAAQ,IAAI,eAAe;AAAA,MAC7B,OAAO,OAAO,EAAC,GAAG,KAAK,gBAAgB,MAAM,GAAG,KAAI;AAAA,MACpD,WAAW,MAAM,YAAY;AAAA,MAC7B,UAAU,KAAK,WAAW;AAAA,MAC1B,QAAQ,KAAK,WAAW;AAAA,IAC5B,CAAC;AAED,QAAI,OAA0B;AAE9B,YAAQ,KAAK,WAAW,UAAU,MAAM;AAAA,MACpC,KAAK,uBAAuB;AACxB,eAAO,IAAI,WAAW,aAAa,KAAK,WAAW,WAAW,KAAK;AACnE;AAAA,MACJ,KAAK,uBAAuB;AACxB,eAAO,IAAI,UAAU,aAAa,KAAK,WAAW,WAAW,MAAM,KAAK,QAAQ,MAAM,GAAG,KAAK;AAC9F;AAAA,IACR;AAEA,WAAO,cAAc,OAAO,WAAW,aACjC,OACA,KAAK,eAAe,MAAM,QAAQ,MAAM,KAAK,SAAS,MAAM,IAAI,CAAC;AAAA,EAC3E;AAAA,EAEU,eACN,MACA,QACA,OACiB;AACjB,UAAM,IAAI,MAAM,sDAAsD;AAAA,EAC1E;AACJ;","names":[]}
1
+ {"version":3,"sources":["../../../../src/entry/content/lifecycle/MountBuilder.ts"],"sourcesContent":["import Builder from \"./Builder\";\nimport IsolationSetup from \"./IsolationSetup\";\nimport {FrameNode, MountNode, MarkerNode, ShadowNode, Node} from \"./nodes\";\n\nimport {isContentScriptFrameNavigation} from \"@shared/content\";\n\nimport type {\n ContentScriptIsolationAssembly,\n ContentScriptNodeAssembly,\n ContentScriptRenderLifecycle,\n ContentScriptRenderOptions,\n} from \"./types\";\n\nimport {\n ContentScriptDefinition,\n ContentScriptIsolation,\n ContentScriptNode,\n ContentScriptPrepareResult,\n ContentScriptProps,\n ContentScriptRenderHandler,\n} from \"@typing/content\";\n\nexport default class MountBuilder<\n Data = unknown,\n Isolation extends `${ContentScriptIsolation}` = `${ContentScriptIsolation}`,\n> extends Builder<Data, Isolation> {\n public constructor(definition: ContentScriptDefinition<Data, Isolation>) {\n super(definition);\n }\n\n protected getProps(node: ContentScriptNode, data: Data): ContentScriptProps<Data> {\n if (!node.container || !node.target) {\n throw new Error(\"Content script render requires a container and target\");\n }\n\n return {\n ...this.getPrepareProps(node.anchor),\n data,\n container: node.container,\n target: node.target,\n boundary: node.boundary,\n };\n }\n\n protected async createNode(\n anchor: Element,\n result: ContentScriptPrepareResult<Data> | undefined\n ): Promise<ContentScriptNodeAssembly> {\n const navigation = isContentScriptFrameNavigation(this.definition.isolation);\n const render = this.definition.render;\n\n if (result === false || (!navigation && (render === undefined || render === true))) {\n return {node: new MarkerNode(new Node(anchor), this.marker)};\n }\n\n const data = result as Data;\n const mountedNode = await this.createMountNode(anchor, data);\n const {node, ready} = this.createIsolation(mountedNode, data);\n\n if (navigation || typeof render !== \"function\") {\n return {node};\n }\n\n const renderer = this.createRenderer(node, render, () => this.getProps(node, data), {ready});\n\n return {node: renderer, renderer};\n }\n\n protected async createMountNode(anchor: Element, data: Data): Promise<ContentScriptNode> {\n const marker = this.marker;\n const container = await this.definition.container({...this.getPrepareProps(anchor), data});\n\n return new MountNode(\n new MarkerNode(new Node(anchor, container), marker),\n this.context.containers,\n this.definition.mount\n );\n }\n\n protected createIsolation(node: ContentScriptNode, data: Data): ContentScriptIsolationAssembly {\n const options = this.definition.isolation;\n\n if (options.type === ContentScriptIsolation.None) {\n return {node};\n }\n\n const setup = new IsolationSetup({\n props: () => ({...this.getPrepareProps(node.anchor), data}),\n container: () => node.container,\n boundary: this.definition.boundary,\n target: this.definition.target,\n });\n\n if (options.type === ContentScriptIsolation.Shadow) {\n const shadow = new ShadowNode(node, options, setup);\n\n return {node: shadow, ready: () => shadow.ready()};\n }\n\n const frame = new FrameNode(node, options, () => this.context.mount(), setup);\n\n return {node: frame, ready: () => frame.ready()};\n }\n\n protected createRenderer(\n node: ContentScriptNode,\n render: ContentScriptRenderHandler<Data>,\n props: () => ContentScriptProps<Data>,\n options: ContentScriptRenderOptions\n ): ContentScriptNode & ContentScriptRenderLifecycle {\n throw new Error(\"Content script rendering requires a renderer adapter\");\n }\n}\n"],"mappings":"AAAA,OAAO,aAAa;AACpB,OAAO,oBAAoB;AAC3B,SAAQ,WAAW,WAAW,YAAY,YAAY,YAAW;AAEjE,SAAQ,sCAAqC;AAS7C;AAAA,EAEI;AAAA,OAKG;AAEP,MAAO,qBAGG,QAAyB;AAAA,EACxB,YAAY,YAAsD;AACrE,UAAM,UAAU;AAAA,EACpB;AAAA,EAEU,SAAS,MAAyB,MAAsC;AAC9E,QAAI,CAAC,KAAK,aAAa,CAAC,KAAK,QAAQ;AACjC,YAAM,IAAI,MAAM,uDAAuD;AAAA,IAC3E;AAEA,WAAO;AAAA,MACH,GAAG,KAAK,gBAAgB,KAAK,MAAM;AAAA,MACnC;AAAA,MACA,WAAW,KAAK;AAAA,MAChB,QAAQ,KAAK;AAAA,MACb,UAAU,KAAK;AAAA,IACnB;AAAA,EACJ;AAAA,EAEA,MAAgB,WACZ,QACA,QACkC;AAClC,UAAM,aAAa,+BAA+B,KAAK,WAAW,SAAS;AAC3E,UAAM,SAAS,KAAK,WAAW;AAE/B,QAAI,WAAW,SAAU,CAAC,eAAe,WAAW,UAAa,WAAW,OAAQ;AAChF,aAAO,EAAC,MAAM,IAAI,WAAW,IAAI,KAAK,MAAM,GAAG,KAAK,MAAM,EAAC;AAAA,IAC/D;AAEA,UAAM,OAAO;AACb,UAAM,cAAc,MAAM,KAAK,gBAAgB,QAAQ,IAAI;AAC3D,UAAM,EAAC,MAAM,MAAK,IAAI,KAAK,gBAAgB,aAAa,IAAI;AAE5D,QAAI,cAAc,OAAO,WAAW,YAAY;AAC5C,aAAO,EAAC,KAAI;AAAA,IAChB;AAEA,UAAM,WAAW,KAAK,eAAe,MAAM,QAAQ,MAAM,KAAK,SAAS,MAAM,IAAI,GAAG,EAAC,MAAK,CAAC;AAE3F,WAAO,EAAC,MAAM,UAAU,SAAQ;AAAA,EACpC;AAAA,EAEA,MAAgB,gBAAgB,QAAiB,MAAwC;AACrF,UAAM,SAAS,KAAK;AACpB,UAAM,YAAY,MAAM,KAAK,WAAW,UAAU,EAAC,GAAG,KAAK,gBAAgB,MAAM,GAAG,KAAI,CAAC;AAEzF,WAAO,IAAI;AAAA,MACP,IAAI,WAAW,IAAI,KAAK,QAAQ,SAAS,GAAG,MAAM;AAAA,MAClD,KAAK,QAAQ;AAAA,MACb,KAAK,WAAW;AAAA,IACpB;AAAA,EACJ;AAAA,EAEU,gBAAgB,MAAyB,MAA4C;AAC3F,UAAM,UAAU,KAAK,WAAW;AAEhC,QAAI,QAAQ,SAAS,uBAAuB,MAAM;AAC9C,aAAO,EAAC,KAAI;AAAA,IAChB;AAEA,UAAM,QAAQ,IAAI,eAAe;AAAA,MAC7B,OAAO,OAAO,EAAC,GAAG,KAAK,gBAAgB,KAAK,MAAM,GAAG,KAAI;AAAA,MACzD,WAAW,MAAM,KAAK;AAAA,MACtB,UAAU,KAAK,WAAW;AAAA,MAC1B,QAAQ,KAAK,WAAW;AAAA,IAC5B,CAAC;AAED,QAAI,QAAQ,SAAS,uBAAuB,QAAQ;AAChD,YAAM,SAAS,IAAI,WAAW,MAAM,SAAS,KAAK;AAElD,aAAO,EAAC,MAAM,QAAQ,OAAO,MAAM,OAAO,MAAM,EAAC;AAAA,IACrD;AAEA,UAAM,QAAQ,IAAI,UAAU,MAAM,SAAS,MAAM,KAAK,QAAQ,MAAM,GAAG,KAAK;AAE5E,WAAO,EAAC,MAAM,OAAO,OAAO,MAAM,MAAM,MAAM,EAAC;AAAA,EACnD;AAAA,EAEU,eACN,MACA,QACA,OACA,SACgD;AAChD,UAAM,IAAI,MAAM,sDAAsD;AAAA,EAC1E;AACJ;","names":[]}
@@ -0,0 +1,7 @@
1
+ /** Tracks independent mount registrations without adding ownership to lifecycle nodes. */
2
+ export default class ContainerRegistry {
3
+ private readonly registrations;
4
+ register(container: Element, anchor: Element): () => void;
5
+ owns(target: Node): boolean;
6
+ clear(): void;
7
+ }
@@ -0,0 +1,45 @@
1
+ class ContainerRegistry {
2
+ registrations = /* @__PURE__ */ new Map();
3
+ register(container, anchor) {
4
+ let registrations = this.registrations.get(container);
5
+ if (!registrations) {
6
+ registrations = /* @__PURE__ */ new Set();
7
+ this.registrations.set(container, registrations);
8
+ }
9
+ const registration = { anchor };
10
+ const current = registrations;
11
+ current.add(registration);
12
+ return () => {
13
+ if (!current.delete(registration)) {
14
+ return;
15
+ }
16
+ if (current.size === 0 && this.registrations.get(container) === current) {
17
+ this.registrations.delete(container);
18
+ }
19
+ };
20
+ }
21
+ owns(target) {
22
+ var _a, _b;
23
+ if (this.registrations.size === 0) {
24
+ return false;
25
+ }
26
+ let current = target;
27
+ while (current) {
28
+ const registrations = this.registrations.get(current);
29
+ const container = current;
30
+ if (registrations && !Array.from(registrations).some(({ anchor }) => container.contains(anchor))) {
31
+ return true;
32
+ }
33
+ const shadowRoot = ((_b = (_a = current.ownerDocument) == null ? void 0 : _a.defaultView) == null ? void 0 : _b.ShadowRoot) ?? ShadowRoot;
34
+ current = current.parentNode ?? (current instanceof shadowRoot ? current.host : null);
35
+ }
36
+ return false;
37
+ }
38
+ clear() {
39
+ this.registrations.clear();
40
+ }
41
+ }
42
+ export {
43
+ ContainerRegistry as default
44
+ };
45
+ //# sourceMappingURL=ContainerRegistry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../src/entry/content/lifecycle/context/ContainerRegistry.ts"],"sourcesContent":["/** Tracks independent mount registrations without adding ownership to lifecycle nodes. */\nexport default class ContainerRegistry {\n private readonly registrations = new Map<Node, Set<{anchor: Element}>>();\n\n public register(container: Element, anchor: Element): () => void {\n let registrations = this.registrations.get(container);\n\n if (!registrations) {\n registrations = new Set();\n this.registrations.set(container, registrations);\n }\n\n const registration = {anchor};\n const current = registrations;\n current.add(registration);\n\n return () => {\n if (!current.delete(registration)) {\n return;\n }\n\n if (current.size === 0 && this.registrations.get(container) === current) {\n this.registrations.delete(container);\n }\n };\n }\n\n public owns(target: Node): boolean {\n if (this.registrations.size === 0) {\n return false;\n }\n\n let current: Node | null = target;\n\n while (current) {\n const registrations = this.registrations.get(current);\n const container = current;\n\n if (registrations && !Array.from(registrations).some(({anchor}) => container.contains(anchor))) {\n return true;\n }\n\n const shadowRoot: typeof ShadowRoot = current.ownerDocument?.defaultView?.ShadowRoot ?? ShadowRoot;\n current = current.parentNode ?? (current instanceof shadowRoot ? current.host : null);\n }\n\n return false;\n }\n\n public clear(): void {\n this.registrations.clear();\n }\n}\n"],"mappings":"AACA,MAAO,kBAAgC;AAAA,EAClB,gBAAgB,oBAAI,IAAkC;AAAA,EAEhE,SAAS,WAAoB,QAA6B;AAC7D,QAAI,gBAAgB,KAAK,cAAc,IAAI,SAAS;AAEpD,QAAI,CAAC,eAAe;AAChB,sBAAgB,oBAAI,IAAI;AACxB,WAAK,cAAc,IAAI,WAAW,aAAa;AAAA,IACnD;AAEA,UAAM,eAAe,EAAC,OAAM;AAC5B,UAAM,UAAU;AAChB,YAAQ,IAAI,YAAY;AAExB,WAAO,MAAM;AACT,UAAI,CAAC,QAAQ,OAAO,YAAY,GAAG;AAC/B;AAAA,MACJ;AAEA,UAAI,QAAQ,SAAS,KAAK,KAAK,cAAc,IAAI,SAAS,MAAM,SAAS;AACrE,aAAK,cAAc,OAAO,SAAS;AAAA,MACvC;AAAA,IACJ;AAAA,EACJ;AAAA,EAEO,KAAK,QAAuB;AA3BvC;AA4BQ,QAAI,KAAK,cAAc,SAAS,GAAG;AAC/B,aAAO;AAAA,IACX;AAEA,QAAI,UAAuB;AAE3B,WAAO,SAAS;AACZ,YAAM,gBAAgB,KAAK,cAAc,IAAI,OAAO;AACpD,YAAM,YAAY;AAElB,UAAI,iBAAiB,CAAC,MAAM,KAAK,aAAa,EAAE,KAAK,CAAC,EAAC,OAAM,MAAM,UAAU,SAAS,MAAM,CAAC,GAAG;AAC5F,eAAO;AAAA,MACX;AAEA,YAAM,eAAgC,mBAAQ,kBAAR,mBAAuB,gBAAvB,mBAAoC,eAAc;AACxF,gBAAU,QAAQ,eAAe,mBAAmB,aAAa,QAAQ,OAAO;AAAA,IACpF;AAEA,WAAO;AAAA,EACX;AAAA,EAEO,QAAc;AACjB,SAAK,cAAc,MAAM;AAAA,EAC7B;AACJ;","names":[]}
@@ -1,10 +1,13 @@
1
- import { ContentScriptContext, ContentScriptEventCallback, ContentScriptEventEmitter, ContentScriptNode, ContentScriptNodeSet } from "../../../../types/content/index.js";
1
+ import type ContainerRegistry from "./ContainerRegistry.js";
2
+ import { ContentScriptNode, ContentScriptContext, ContentScriptEventCallback, ContentScriptEventEmitter } from "../../../../types/content/index.js";
2
3
  export default class Context implements ContentScriptContext {
3
4
  protected readonly emitter: ContentScriptEventEmitter;
4
- protected readonly collection: ContentScriptNodeSet;
5
+ private readonly registry;
6
+ protected readonly collection: Set<ContentScriptNode>;
5
7
  private unmounting;
6
- constructor(emitter: ContentScriptEventEmitter);
8
+ constructor(emitter: ContentScriptEventEmitter, registry: ContainerRegistry);
7
9
  get nodes(): ReadonlySet<ContentScriptNode>;
10
+ owns(target: Node): boolean;
8
11
  mount(): void;
9
12
  unmount(): void;
10
13
  remove(node: ContentScriptNode): void;
@@ -1,13 +1,18 @@
1
1
  class Context {
2
- constructor(emitter) {
2
+ constructor(emitter, registry) {
3
3
  this.emitter = emitter;
4
+ this.registry = registry;
4
5
  }
5
6
  emitter;
7
+ registry;
6
8
  collection = /* @__PURE__ */ new Set();
7
9
  unmounting = false;
8
10
  get nodes() {
9
11
  return this.collection;
10
12
  }
13
+ owns(target) {
14
+ return this.registry.owns(target);
15
+ }
11
16
  mount() {
12
17
  if (this.unmounting) {
13
18
  return;
@@ -41,21 +46,31 @@ class Context {
41
46
  if (!this.collection.delete(node)) {
42
47
  return;
43
48
  }
44
- node.unmount();
45
- this.emitter.emitRemove(node);
49
+ try {
50
+ node.unmount();
51
+ } finally {
52
+ this.emitter.emitRemove(node);
53
+ }
46
54
  }
47
55
  clear() {
48
56
  const unmounting = this.unmounting;
49
57
  this.unmounting = true;
58
+ const errors = [];
50
59
  try {
51
60
  for (const node of this.collection) {
52
- node.unmount();
53
- this.collection.delete(node);
54
- this.emitter.emitRemove(node);
61
+ try {
62
+ this.remove(node);
63
+ } catch (error) {
64
+ errors.push(error);
65
+ }
55
66
  }
56
67
  } finally {
68
+ this.registry.clear();
57
69
  this.unmounting = unmounting;
58
70
  }
71
+ if (errors.length > 0) {
72
+ throw new AggregateError(errors, "Content script context cleanup failed");
73
+ }
59
74
  }
60
75
  watch(callback) {
61
76
  this.emitter.on(callback);
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../src/entry/content/lifecycle/context/Context.ts"],"sourcesContent":["import {\n ContentScriptContext,\n ContentScriptEventCallback,\n ContentScriptEventEmitter,\n ContentScriptNode,\n ContentScriptNodeSet,\n} from \"@typing/content\";\n\nexport default class Context implements ContentScriptContext {\n protected readonly collection: ContentScriptNodeSet = new Set();\n private unmounting = false;\n\n constructor(protected readonly emitter: ContentScriptEventEmitter) {}\n\n public get nodes(): ReadonlySet<ContentScriptNode> {\n return this.collection;\n }\n\n public mount(): void {\n if (this.unmounting) {\n return;\n }\n\n for (const node of this.collection) {\n if (!node.anchor.isConnected) {\n node.unmount();\n\n this.collection.delete(node);\n\n this.emitter.emitRemove(node);\n\n continue;\n }\n\n node.mount();\n }\n }\n\n public unmount(): void {\n const unmounting = this.unmounting;\n this.unmounting = true;\n\n try {\n for (const node of this.collection) {\n node.unmount();\n\n if (!node.anchor.isConnected) {\n this.collection.delete(node);\n\n this.emitter.emitRemove(node);\n }\n }\n } finally {\n this.unmounting = unmounting;\n }\n }\n\n public remove(node: ContentScriptNode): void {\n if (!this.collection.delete(node)) {\n return;\n }\n\n node.unmount();\n this.emitter.emitRemove(node);\n }\n\n public clear(): void {\n const unmounting = this.unmounting;\n this.unmounting = true;\n\n try {\n for (const node of this.collection) {\n node.unmount();\n this.collection.delete(node);\n this.emitter.emitRemove(node);\n }\n } finally {\n this.unmounting = unmounting;\n }\n }\n\n public watch(callback: ContentScriptEventCallback): () => void {\n this.emitter.on(callback);\n\n return () => {\n this.emitter.off(callback);\n };\n }\n\n public unwatch(): void {\n this.emitter.removeAllListeners();\n }\n}\n"],"mappings":"AAQA,MAAO,QAAsD;AAAA,EAIzD,YAA+B,SAAoC;AAApC;AAAA,EAAqC;AAAA,EAArC;AAAA,EAHZ,aAAmC,oBAAI,IAAI;AAAA,EACtD,aAAa;AAAA,EAIrB,IAAW,QAAwC;AAC/C,WAAO,KAAK;AAAA,EAChB;AAAA,EAEO,QAAc;AACjB,QAAI,KAAK,YAAY;AACjB;AAAA,IACJ;AAEA,eAAW,QAAQ,KAAK,YAAY;AAChC,UAAI,CAAC,KAAK,OAAO,aAAa;AAC1B,aAAK,QAAQ;AAEb,aAAK,WAAW,OAAO,IAAI;AAE3B,aAAK,QAAQ,WAAW,IAAI;AAE5B;AAAA,MACJ;AAEA,WAAK,MAAM;AAAA,IACf;AAAA,EACJ;AAAA,EAEO,UAAgB;AACnB,UAAM,aAAa,KAAK;AACxB,SAAK,aAAa;AAElB,QAAI;AACA,iBAAW,QAAQ,KAAK,YAAY;AAChC,aAAK,QAAQ;AAEb,YAAI,CAAC,KAAK,OAAO,aAAa;AAC1B,eAAK,WAAW,OAAO,IAAI;AAE3B,eAAK,QAAQ,WAAW,IAAI;AAAA,QAChC;AAAA,MACJ;AAAA,IACJ,UAAE;AACE,WAAK,aAAa;AAAA,IACtB;AAAA,EACJ;AAAA,EAEO,OAAO,MAA+B;AACzC,QAAI,CAAC,KAAK,WAAW,OAAO,IAAI,GAAG;AAC/B;AAAA,IACJ;AAEA,SAAK,QAAQ;AACb,SAAK,QAAQ,WAAW,IAAI;AAAA,EAChC;AAAA,EAEO,QAAc;AACjB,UAAM,aAAa,KAAK;AACxB,SAAK,aAAa;AAElB,QAAI;AACA,iBAAW,QAAQ,KAAK,YAAY;AAChC,aAAK,QAAQ;AACb,aAAK,WAAW,OAAO,IAAI;AAC3B,aAAK,QAAQ,WAAW,IAAI;AAAA,MAChC;AAAA,IACJ,UAAE;AACE,WAAK,aAAa;AAAA,IACtB;AAAA,EACJ;AAAA,EAEO,MAAM,UAAkD;AAC3D,SAAK,QAAQ,GAAG,QAAQ;AAExB,WAAO,MAAM;AACT,WAAK,QAAQ,IAAI,QAAQ;AAAA,IAC7B;AAAA,EACJ;AAAA,EAEO,UAAgB;AACnB,SAAK,QAAQ,mBAAmB;AAAA,EACpC;AACJ;","names":[]}
1
+ {"version":3,"sources":["../../../../../src/entry/content/lifecycle/context/Context.ts"],"sourcesContent":["import type ContainerRegistry from \"./ContainerRegistry\";\n\nimport {\n ContentScriptNode,\n ContentScriptContext,\n ContentScriptEventCallback,\n ContentScriptEventEmitter,\n} from \"@typing/content\";\n\nexport default class Context implements ContentScriptContext {\n protected readonly collection = new Set<ContentScriptNode>();\n private unmounting = false;\n\n constructor(\n protected readonly emitter: ContentScriptEventEmitter,\n private readonly registry: ContainerRegistry\n ) {}\n\n public get nodes(): ReadonlySet<ContentScriptNode> {\n return this.collection;\n }\n\n public owns(target: Node): boolean {\n return this.registry.owns(target);\n }\n\n public mount(): void {\n if (this.unmounting) {\n return;\n }\n\n for (const node of this.collection) {\n if (!node.anchor.isConnected) {\n node.unmount();\n\n this.collection.delete(node);\n\n this.emitter.emitRemove(node);\n\n continue;\n }\n\n node.mount();\n }\n }\n\n public unmount(): void {\n const unmounting = this.unmounting;\n this.unmounting = true;\n\n try {\n for (const node of this.collection) {\n node.unmount();\n\n if (!node.anchor.isConnected) {\n this.collection.delete(node);\n\n this.emitter.emitRemove(node);\n }\n }\n } finally {\n this.unmounting = unmounting;\n }\n }\n\n public remove(node: ContentScriptNode): void {\n if (!this.collection.delete(node)) {\n return;\n }\n\n try {\n node.unmount();\n } finally {\n this.emitter.emitRemove(node);\n }\n }\n\n public clear(): void {\n const unmounting = this.unmounting;\n\n this.unmounting = true;\n\n const errors: unknown[] = [];\n\n try {\n for (const node of this.collection) {\n try {\n this.remove(node);\n } catch (error) {\n errors.push(error);\n }\n }\n } finally {\n this.registry.clear();\n this.unmounting = unmounting;\n }\n\n if (errors.length > 0) {\n throw new AggregateError(errors, \"Content script context cleanup failed\");\n }\n }\n\n public watch(callback: ContentScriptEventCallback): () => void {\n this.emitter.on(callback);\n\n return () => {\n this.emitter.off(callback);\n };\n }\n\n public unwatch(): void {\n this.emitter.removeAllListeners();\n }\n}\n"],"mappings":"AASA,MAAO,QAAsD;AAAA,EAIzD,YACuB,SACF,UACnB;AAFqB;AACF;AAAA,EAClB;AAAA,EAFoB;AAAA,EACF;AAAA,EALF,aAAa,oBAAI,IAAuB;AAAA,EACnD,aAAa;AAAA,EAOrB,IAAW,QAAwC;AAC/C,WAAO,KAAK;AAAA,EAChB;AAAA,EAEO,KAAK,QAAuB;AAC/B,WAAO,KAAK,SAAS,KAAK,MAAM;AAAA,EACpC;AAAA,EAEO,QAAc;AACjB,QAAI,KAAK,YAAY;AACjB;AAAA,IACJ;AAEA,eAAW,QAAQ,KAAK,YAAY;AAChC,UAAI,CAAC,KAAK,OAAO,aAAa;AAC1B,aAAK,QAAQ;AAEb,aAAK,WAAW,OAAO,IAAI;AAE3B,aAAK,QAAQ,WAAW,IAAI;AAE5B;AAAA,MACJ;AAEA,WAAK,MAAM;AAAA,IACf;AAAA,EACJ;AAAA,EAEO,UAAgB;AACnB,UAAM,aAAa,KAAK;AACxB,SAAK,aAAa;AAElB,QAAI;AACA,iBAAW,QAAQ,KAAK,YAAY;AAChC,aAAK,QAAQ;AAEb,YAAI,CAAC,KAAK,OAAO,aAAa;AAC1B,eAAK,WAAW,OAAO,IAAI;AAE3B,eAAK,QAAQ,WAAW,IAAI;AAAA,QAChC;AAAA,MACJ;AAAA,IACJ,UAAE;AACE,WAAK,aAAa;AAAA,IACtB;AAAA,EACJ;AAAA,EAEO,OAAO,MAA+B;AACzC,QAAI,CAAC,KAAK,WAAW,OAAO,IAAI,GAAG;AAC/B;AAAA,IACJ;AAEA,QAAI;AACA,WAAK,QAAQ;AAAA,IACjB,UAAE;AACE,WAAK,QAAQ,WAAW,IAAI;AAAA,IAChC;AAAA,EACJ;AAAA,EAEO,QAAc;AACjB,UAAM,aAAa,KAAK;AAExB,SAAK,aAAa;AAElB,UAAM,SAAoB,CAAC;AAE3B,QAAI;AACA,iBAAW,QAAQ,KAAK,YAAY;AAChC,YAAI;AACA,eAAK,OAAO,IAAI;AAAA,QACpB,SAAS,OAAO;AACZ,iBAAO,KAAK,KAAK;AAAA,QACrB;AAAA,MACJ;AAAA,IACJ,UAAE;AACE,WAAK,SAAS,MAAM;AACpB,WAAK,aAAa;AAAA,IACtB;AAEA,QAAI,OAAO,SAAS,GAAG;AACnB,YAAM,IAAI,eAAe,QAAQ,uCAAuC;AAAA,IAC5E;AAAA,EACJ;AAAA,EAEO,MAAM,UAAkD;AAC3D,SAAK,QAAQ,GAAG,QAAQ;AAExB,WAAO,MAAM;AACT,WAAK,QAAQ,IAAI,QAAQ;AAAA,IAC7B;AAAA,EACJ;AAAA,EAEO,UAAgB;AACnB,SAAK,QAAQ,mBAAmB;AAAA,EACpC;AACJ;","names":[]}
@@ -1,5 +1,8 @@
1
1
  import Context from "./Context.js";
2
- import { ContentScriptNode } from "../../../../types/content/index.js";
2
+ import ContainerRegistry from "./ContainerRegistry.js";
3
+ import type { ContentScriptNode, ContentScriptEventEmitter } from "../../../../types/content/index.js";
3
4
  export default class ManagedContext extends Context {
5
+ readonly containers: ContainerRegistry;
6
+ constructor(emitter: ContentScriptEventEmitter);
4
7
  add(node: ContentScriptNode): this;
5
8
  }
@@ -1,5 +1,12 @@
1
1
  import Context from "./Context.js";
2
+ import ContainerRegistry from "./ContainerRegistry.js";
2
3
  class ManagedContext extends Context {
4
+ containers;
5
+ constructor(emitter) {
6
+ const containers = new ContainerRegistry();
7
+ super(emitter, containers);
8
+ this.containers = containers;
9
+ }
3
10
  add(node) {
4
11
  this.collection.add(node);
5
12
  this.emitter.emitAdd(node);
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../src/entry/content/lifecycle/context/ManagedContext.ts"],"sourcesContent":["import Context from \"./Context\";\n\nimport {ContentScriptNode} from \"@typing/content\";\n\nexport default class ManagedContext extends Context {\n public add(node: ContentScriptNode): this {\n this.collection.add(node);\n\n this.emitter.emitAdd(node);\n\n return this;\n }\n}\n"],"mappings":"AAAA,OAAO,aAAa;AAIpB,MAAO,uBAAqC,QAAQ;AAAA,EACzC,IAAI,MAA+B;AACtC,SAAK,WAAW,IAAI,IAAI;AAExB,SAAK,QAAQ,QAAQ,IAAI;AAEzB,WAAO;AAAA,EACX;AACJ;","names":[]}
1
+ {"version":3,"sources":["../../../../../src/entry/content/lifecycle/context/ManagedContext.ts"],"sourcesContent":["import Context from \"./Context\";\nimport ContainerRegistry from \"./ContainerRegistry\";\nimport type {ContentScriptNode, ContentScriptEventEmitter} from \"@typing/content\";\n\nexport default class ManagedContext extends Context {\n public readonly containers: ContainerRegistry;\n\n constructor(emitter: ContentScriptEventEmitter) {\n const containers = new ContainerRegistry();\n super(emitter, containers);\n this.containers = containers;\n }\n\n public add(node: ContentScriptNode): this {\n this.collection.add(node);\n\n this.emitter.emitAdd(node);\n\n return this;\n }\n}\n"],"mappings":"AAAA,OAAO,aAAa;AACpB,OAAO,uBAAuB;AAG9B,MAAO,uBAAqC,QAAQ;AAAA,EAChC;AAAA,EAEhB,YAAY,SAAoC;AAC5C,UAAM,aAAa,IAAI,kBAAkB;AACzC,UAAM,SAAS,UAAU;AACzB,SAAK,aAAa;AAAA,EACtB;AAAA,EAEO,IAAI,MAA+B;AACtC,SAAK,WAAW,IAAI,IAAI;AAExB,SAAK,QAAQ,QAAQ,IAAI;AAEzB,WAAO;AAAA,EACX;AACJ;","names":[]}