@jsenv/core 36.3.0 → 37.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 (64) hide show
  1. package/dist/js/autoreload.js +6 -5
  2. package/dist/js/import_meta_hot.js +4 -4
  3. package/dist/js/server_events_client.js +422 -304
  4. package/dist/jsenv_core.js +3819 -3256
  5. package/package.json +18 -17
  6. package/src/build/build.js +342 -658
  7. package/src/build/build_urls_generator.js +8 -8
  8. package/src/build/build_versions_manager.js +495 -0
  9. package/src/build/version_mappings_injection.js +27 -16
  10. package/src/dev/file_service.js +80 -91
  11. package/src/dev/start_dev_server.js +5 -3
  12. package/src/kitchen/errors.js +16 -16
  13. package/src/kitchen/fetched_content_compliance.js +4 -8
  14. package/src/kitchen/kitchen.js +367 -939
  15. package/src/kitchen/prepend_content.js +13 -35
  16. package/src/kitchen/url_graph/references.js +713 -0
  17. package/src/kitchen/url_graph/sort_by_dependencies.js +2 -2
  18. package/src/kitchen/url_graph/url_content.js +96 -0
  19. package/src/kitchen/url_graph/url_graph.js +439 -0
  20. package/src/kitchen/url_graph/url_graph_report.js +6 -4
  21. package/src/kitchen/url_graph/url_graph_visitor.js +14 -12
  22. package/src/kitchen/url_graph/url_info_transformations.js +180 -184
  23. package/src/plugins/autoreload/client/autoreload.js +1 -0
  24. package/src/plugins/autoreload/client/reload.js +6 -6
  25. package/src/plugins/autoreload/jsenv_plugin_autoreload.js +2 -2
  26. package/src/plugins/autoreload/jsenv_plugin_autoreload_client.js +2 -2
  27. package/src/plugins/autoreload/jsenv_plugin_autoreload_server.js +84 -78
  28. package/src/plugins/autoreload/jsenv_plugin_hot_search_param.js +52 -0
  29. package/src/plugins/cache_control/jsenv_plugin_cache_control.js +1 -1
  30. package/src/plugins/commonjs_globals/jsenv_plugin_commonjs_globals.js +2 -2
  31. package/src/plugins/global_scenarios/jsenv_plugin_global_scenarios.js +3 -3
  32. package/src/plugins/import_meta_hot/client/import_meta_hot.js +4 -4
  33. package/src/plugins/import_meta_hot/jsenv_plugin_import_meta_hot.js +18 -20
  34. package/src/plugins/import_meta_scenarios/jsenv_plugin_import_meta_scenarios.js +2 -2
  35. package/src/plugins/importmap/jsenv_plugin_importmap.js +35 -37
  36. package/src/plugins/inlining/jsenv_plugin_inlining.js +1 -17
  37. package/src/plugins/inlining/jsenv_plugin_inlining_as_data_url.js +70 -50
  38. package/src/plugins/inlining/jsenv_plugin_inlining_into_html.js +72 -54
  39. package/src/plugins/plugin_controller.js +92 -27
  40. package/src/plugins/protocol_file/jsenv_plugin_protocol_file.js +18 -20
  41. package/src/plugins/reference_analysis/css/jsenv_plugin_css_reference_analysis.js +4 -5
  42. package/src/plugins/reference_analysis/data_urls/jsenv_plugin_data_urls_analysis.js +18 -16
  43. package/src/plugins/reference_analysis/directory/jsenv_plugin_directory_reference_analysis.js +13 -20
  44. package/src/plugins/reference_analysis/html/jsenv_plugin_html_reference_analysis.js +55 -72
  45. package/src/plugins/reference_analysis/js/jsenv_plugin_js_reference_analysis.js +33 -42
  46. package/src/plugins/reference_analysis/jsenv_plugin_reference_analysis.js +16 -7
  47. package/src/plugins/reference_analysis/webmanifest/jsenv_plugin_webmanifest_reference_analysis.js +4 -3
  48. package/src/plugins/resolution_node_esm/jsenv_plugin_node_esm_resolution.js +16 -6
  49. package/src/plugins/resolution_node_esm/node_esm_resolver.js +30 -24
  50. package/src/plugins/resolution_web/jsenv_plugin_web_resolution.js +8 -5
  51. package/src/plugins/ribbon/jsenv_plugin_ribbon.js +3 -3
  52. package/src/plugins/server_events/client/server_events_client.js +460 -15
  53. package/src/plugins/server_events/jsenv_plugin_server_events_client_injection.js +13 -29
  54. package/src/plugins/version_search_param/jsenv_plugin_version_search_param.js +1 -1
  55. package/src/build/version_generator.js +0 -19
  56. package/src/kitchen/url_graph/url_graph_loader.js +0 -77
  57. package/src/kitchen/url_graph.js +0 -322
  58. package/src/plugins/autoreload/jsenv_plugin_hmr.js +0 -42
  59. package/src/plugins/resolution_node_esm/url_type_from_reference.js +0 -13
  60. package/src/plugins/server_events/client/connection_manager.js +0 -170
  61. package/src/plugins/server_events/client/event_source_connection.js +0 -83
  62. package/src/plugins/server_events/client/events_manager.js +0 -75
  63. package/src/plugins/server_events/client/web_socket_connection.js +0 -81
  64. /package/src/kitchen/{url_specifier_encoding.js → url_graph/url_specifier_encoding.js} +0 -0
@@ -8,7 +8,6 @@
8
8
  */
9
9
 
10
10
  import { readFileSync } from "node:fs";
11
- import { bufferToEtag } from "@jsenv/filesystem";
12
11
  import {
13
12
  applyNodeEsmResolution,
14
13
  readCustomConditionsFromProcessArgs,
@@ -29,19 +28,22 @@ export const createNodeEsmResolver = ({
29
28
  "import",
30
29
  ];
31
30
 
32
- return (reference, context) => {
31
+ return (reference) => {
33
32
  if (reference.type === "package_json") {
34
33
  return reference.specifier;
35
34
  }
35
+ const { ownerUrlInfo } = reference;
36
36
  if (reference.specifier === "/") {
37
- const { mainFilePath, rootDirectoryUrl } = context;
37
+ const { mainFilePath, rootDirectoryUrl } = ownerUrlInfo.context;
38
38
  return String(new URL(mainFilePath, rootDirectoryUrl));
39
39
  }
40
40
  if (reference.specifier[0] === "/") {
41
- return new URL(reference.specifier.slice(1), context.rootDirectoryUrl)
42
- .href;
41
+ return new URL(
42
+ reference.specifier.slice(1),
43
+ ownerUrlInfo.context.rootDirectoryUrl,
44
+ ).href;
43
45
  }
44
- const parentUrl = reference.baseUrl || reference.parentUrl;
46
+ const parentUrl = reference.baseUrl || ownerUrlInfo.url;
45
47
  if (!parentUrl.startsWith("file:")) {
46
48
  return new URL(reference.specifier, parentUrl).href;
47
49
  }
@@ -51,7 +53,7 @@ export const createNodeEsmResolver = ({
51
53
  specifier: reference.specifier,
52
54
  preservesSymlink,
53
55
  });
54
- if (context.dev) {
56
+ if (ownerUrlInfo.context.dev) {
55
57
  const dependsOnPackageJson =
56
58
  type !== "relative_specifier" &&
57
59
  type !== "absolute_specifier" &&
@@ -62,7 +64,6 @@ export const createNodeEsmResolver = ({
62
64
  // must be invalidated when corresponding package.json changes
63
65
  addRelationshipWithPackageJson({
64
66
  reference,
65
- context,
66
67
  packageJsonUrl: `${packageDirectoryUrl}package.json`,
67
68
  field: type.startsWith("field:")
68
69
  ? `#${type.slice("field:".length)}`
@@ -70,7 +71,7 @@ export const createNodeEsmResolver = ({
70
71
  });
71
72
  }
72
73
  }
73
- if (context.dev) {
74
+ if (ownerUrlInfo.context.dev) {
74
75
  // without this check a file inside a project without package.json
75
76
  // could be considered as a node module if there is a ancestor package.json
76
77
  // but we want to version only node modules
@@ -78,7 +79,7 @@ export const createNodeEsmResolver = ({
78
79
  const packageDirectoryUrl = defaultLookupPackageScope(url);
79
80
  if (
80
81
  packageDirectoryUrl &&
81
- packageDirectoryUrl !== context.rootDirectoryUrl
82
+ packageDirectoryUrl !== ownerUrlInfo.context.rootDirectoryUrl
82
83
  ) {
83
84
  const packageVersion =
84
85
  defaultReadPackageJson(packageDirectoryUrl).version;
@@ -86,7 +87,6 @@ export const createNodeEsmResolver = ({
86
87
  if (packageVersion) {
87
88
  addRelationshipWithPackageJson({
88
89
  reference,
89
- context,
90
90
  packageJsonUrl: `${packageDirectoryUrl}package.json`,
91
91
  field: "version",
92
92
  hasVersioningEffect: true,
@@ -101,29 +101,35 @@ export const createNodeEsmResolver = ({
101
101
  };
102
102
 
103
103
  const addRelationshipWithPackageJson = ({
104
- context,
104
+ reference,
105
105
  packageJsonUrl,
106
106
  field,
107
107
  hasVersioningEffect = false,
108
108
  }) => {
109
- const referenceFound = context.referenceUtils.find(
110
- (ref) => ref.type === "package_json" && ref.subtype === field,
111
- );
112
- if (referenceFound) {
113
- return;
109
+ const { ownerUrlInfo } = reference;
110
+ for (const referenceToOther of ownerUrlInfo.referenceToOthersSet) {
111
+ if (
112
+ referenceToOther.type === "package_json" &&
113
+ referenceToOther.subtype === field
114
+ ) {
115
+ return;
116
+ }
114
117
  }
115
- const [, packageJsonUrlInfo] = context.referenceUtils.inject({
118
+ const packageJsonReference = reference.addImplicit({
116
119
  type: "package_json",
117
120
  subtype: field,
118
121
  specifier: packageJsonUrl,
119
- isImplicit: true,
120
122
  hasVersioningEffect,
123
+ isWeak: true,
121
124
  });
122
- if (packageJsonUrlInfo.type === undefined) {
125
+ // we don't cook package.json files, we just maintain their content
126
+ // to be able to check if it has changed later on
127
+ if (packageJsonReference.urlInfo.content === undefined) {
123
128
  const packageJsonContentAsBuffer = readFileSync(new URL(packageJsonUrl));
124
- packageJsonUrlInfo.type = "json";
125
- packageJsonUrlInfo.content = String(packageJsonContentAsBuffer);
126
- packageJsonUrlInfo.originalContentEtag = packageJsonUrlInfo.contentEtag =
127
- bufferToEtag(packageJsonContentAsBuffer);
129
+ packageJsonReference.urlInfo.type = "json";
130
+ packageJsonReference.urlInfo.kitchen.urlInfoTransformer.setContent(
131
+ packageJsonReference.urlInfo,
132
+ String(packageJsonContentAsBuffer),
133
+ );
128
134
  }
129
135
  };
@@ -2,20 +2,23 @@ export const jsenvPluginWebResolution = () => {
2
2
  return {
3
3
  name: "jsenv:web_resolution",
4
4
  appliesDuring: "*",
5
- resolveReference: (reference, context) => {
5
+ resolveReference: (reference) => {
6
+ const { ownerUrlInfo } = reference;
6
7
  if (reference.specifier === "/") {
7
- const { mainFilePath, rootDirectoryUrl } = context;
8
+ const { mainFilePath, rootDirectoryUrl } = ownerUrlInfo.context;
8
9
  return String(new URL(mainFilePath, rootDirectoryUrl));
9
10
  }
10
11
  if (reference.specifier[0] === "/") {
11
- return new URL(reference.specifier.slice(1), context.rootDirectoryUrl)
12
- .href;
12
+ return new URL(
13
+ reference.specifier.slice(1),
14
+ ownerUrlInfo.context.rootDirectoryUrl,
15
+ ).href;
13
16
  }
14
17
  return new URL(
15
18
  reference.specifier,
16
19
  // baseUrl happens second argument to new URL() is different from
17
20
  // import.meta.url or document.currentScript.src
18
- reference.baseUrl || reference.parentUrl,
21
+ reference.baseUrl || ownerUrlInfo.url,
19
22
  ).href;
20
23
  },
21
24
  };
@@ -24,7 +24,7 @@ export const jsenvPluginRibbon = ({
24
24
  name: "jsenv:ribbon",
25
25
  appliesDuring: "dev",
26
26
  transformUrlContent: {
27
- html: (urlInfo, context) => {
27
+ html: (urlInfo) => {
28
28
  if (urlInfo.data.isJsenvToolbar || urlInfo.data.noribbon) {
29
29
  return null;
30
30
  }
@@ -36,14 +36,14 @@ export const jsenvPluginRibbon = ({
36
36
  return null;
37
37
  }
38
38
  const htmlAst = parseHtmlString(urlInfo.content);
39
- const [ribbonClientFileReference] = context.referenceUtils.inject({
39
+ const ribbonClientFileReference = urlInfo.dependencies.inject({
40
40
  type: "script",
41
41
  subtype: "js_module",
42
42
  expectedType: "js_module",
43
43
  specifier: ribbonClientFileUrl.href,
44
44
  });
45
45
  const paramsJson = JSON.stringify(
46
- { text: context.dev ? "DEV" : "BUILD" },
46
+ { text: urlInfo.context.dev ? "DEV" : "BUILD" },
47
47
  null,
48
48
  " ",
49
49
  );
@@ -1,16 +1,461 @@
1
- import { createWebSocketConnection } from "./web_socket_connection.js";
2
-
3
- const websocketScheme = self.location.protocol === "https:" ? "wss" : "ws";
4
- const websocketUrl = `${websocketScheme}://${self.location.host}${self.location.pathname}${self.location.search}`;
5
- const websocketConnection = createWebSocketConnection(websocketUrl, {
6
- retry: true,
7
- retryAllocatedMs: 10_000,
8
- });
9
- const { readyState, connect, disconnect, listenEvents } = websocketConnection;
10
- window.__server_events__ = {
11
- readyState,
12
- connect,
13
- disconnect,
14
- listenEvents,
1
+ let createEventsManager;
2
+ events_manager: {
3
+ createEventsManager = ({ effect = () => {} } = {}) => {
4
+ const callbacksMap = new Map();
5
+ let cleanup;
6
+ const addCallbacks = (namedCallbacks) => {
7
+ let callbacksMapSize = callbacksMap.size;
8
+ Object.keys(namedCallbacks).forEach((eventName) => {
9
+ const callback = namedCallbacks[eventName];
10
+ const existingCallbacks = callbacksMap.get(eventName);
11
+ let callbacks;
12
+ if (existingCallbacks) {
13
+ callbacks = existingCallbacks;
14
+ } else {
15
+ callbacks = [];
16
+ callbacksMap.set(eventName, callbacks);
17
+ }
18
+ callbacks.push(callback);
19
+ });
20
+ if (effect && callbacksMapSize === 0 && callbacksMapSize.size > 0) {
21
+ cleanup = effect();
22
+ }
23
+
24
+ let removed = false;
25
+ return () => {
26
+ if (removed) return;
27
+ removed = true;
28
+ callbacksMapSize = callbacksMap.size;
29
+ Object.keys(namedCallbacks).forEach((eventName) => {
30
+ const callback = namedCallbacks[eventName];
31
+ const callbacks = callbacksMap.get(eventName);
32
+ if (callbacks) {
33
+ const index = callbacks.indexOf(callback);
34
+ if (index > -1) {
35
+ callbacks.splice(index, 1);
36
+ if (callbacks.length === 0) {
37
+ callbacksMap.delete(eventName);
38
+ }
39
+ }
40
+ }
41
+ });
42
+ namedCallbacks = null; // allow garbage collect
43
+ if (
44
+ cleanup &&
45
+ typeof cleanup === "function" &&
46
+ callbacksMapSize > 0 &&
47
+ callbacksMapSize.size === 0
48
+ ) {
49
+ cleanup();
50
+ cleanup = null;
51
+ }
52
+ };
53
+ };
54
+
55
+ const triggerCallbacks = (event) => {
56
+ const callbacks = callbacksMap.get(event.type);
57
+ if (callbacks) {
58
+ callbacks.forEach((callback) => {
59
+ callback(event);
60
+ });
61
+ }
62
+ };
63
+
64
+ const destroy = () => {
65
+ callbacksMap.clear();
66
+ if (cleanup) {
67
+ cleanup();
68
+ cleanup = null;
69
+ }
70
+ };
71
+
72
+ return {
73
+ addCallbacks,
74
+ triggerCallbacks,
75
+ destroy,
76
+ };
77
+ };
78
+ }
79
+
80
+ let createConnectionManager;
81
+ connection_manager: {
82
+ const READY_STATES = {
83
+ CONNECTING: "connecting",
84
+ OPEN: "open",
85
+ CLOSING: "closing",
86
+ CLOSED: "closed",
87
+ };
88
+
89
+ createConnectionManager = (
90
+ attemptConnection,
91
+ { logs, retry, retryAfter, retryMaxAttempt, retryAllocatedMs },
92
+ ) => {
93
+ const readyState = {
94
+ value: READY_STATES.CLOSED,
95
+ goTo: (value) => {
96
+ if (value === readyState.value) {
97
+ return;
98
+ }
99
+ readyState.value = value;
100
+ readyState.onchange();
101
+ },
102
+ onchange: () => {},
103
+ };
104
+
105
+ let _disconnect = () => {};
106
+ const connect = () => {
107
+ if (
108
+ readyState.value === READY_STATES.CONNECTING ||
109
+ readyState.value === READY_STATES.OPEN
110
+ ) {
111
+ return;
112
+ }
113
+
114
+ let retryCount = 0;
115
+ let msSpent = 0;
116
+ const attempt = () => {
117
+ readyState.goTo(READY_STATES.CONNECTING);
118
+ let timeout;
119
+ const cancelAttempt = attemptConnection({
120
+ onClosed: () => {
121
+ if (!retry) {
122
+ readyState.goTo(READY_STATES.CLOSED);
123
+ if (logs) {
124
+ console.info(`[jsenv] failed to connect to server`);
125
+ }
126
+ return;
127
+ }
128
+ if (retryCount > retryMaxAttempt) {
129
+ readyState.goTo(READY_STATES.CLOSED);
130
+ if (logs) {
131
+ console.info(
132
+ `[jsenv] could not connect to server after ${retryMaxAttempt} attempt`,
133
+ );
134
+ }
135
+ return;
136
+ }
137
+ if (retryAllocatedMs && msSpent > retryAllocatedMs) {
138
+ readyState.goTo(READY_STATES.CLOSED);
139
+ if (logs) {
140
+ console.info(
141
+ `[jsenv] could not connect to server in less than ${retryAllocatedMs}ms`,
142
+ );
143
+ }
144
+ return;
145
+ }
146
+ // if closed while open -> connection lost
147
+ // otherwise it's the attempt to connect for the first time
148
+ // or to reconnect
149
+ if (readyState.value === READY_STATES.OPEN) {
150
+ if (logs) {
151
+ console.info(
152
+ `[jsenv] server connection lost; retrying to connect`,
153
+ );
154
+ }
155
+ }
156
+ retryCount++;
157
+ timeout = setTimeout(() => {
158
+ msSpent += retryAfter;
159
+ attempt();
160
+ }, retryAfter);
161
+ },
162
+ onOpen: () => {
163
+ readyState.goTo(READY_STATES.OPEN);
164
+ if (logs) {
165
+ // console.info(`[jsenv] connected to server`);
166
+ }
167
+ },
168
+ });
169
+ _disconnect = () => {
170
+ cancelAttempt();
171
+ clearTimeout(timeout);
172
+ readyState.goTo(READY_STATES.CLOSED);
173
+ };
174
+ };
175
+ attempt();
176
+ };
177
+
178
+ const disconnect = () => {
179
+ if (
180
+ readyState.value !== READY_STATES.CONNECTING &&
181
+ readyState.value !== READY_STATES.OPEN
182
+ ) {
183
+ if (logs) {
184
+ console.warn(
185
+ `disconnect() ignored because connection is ${readyState.value}`,
186
+ );
187
+ }
188
+ return null;
189
+ }
190
+ return _disconnect();
191
+ };
192
+
193
+ const removePageUnloadListener = listenPageUnload(() => {
194
+ if (
195
+ readyState.value === READY_STATES.CONNECTING ||
196
+ readyState.value === READY_STATES.OPEN
197
+ ) {
198
+ _disconnect();
199
+ }
200
+ });
201
+
202
+ return {
203
+ readyState,
204
+ connect,
205
+ disconnect,
206
+ destroy: () => {
207
+ removePageUnloadListener();
208
+ disconnect();
209
+ },
210
+ };
211
+ };
212
+
213
+ // const listenPageMightFreeze = (callback) => {
214
+ // const removePageHideListener = listenEvent(window, "pagehide", (pageHideEvent) => {
215
+ // if (pageHideEvent.persisted === true) {
216
+ // callback(pageHideEvent)
217
+ // }
218
+ // })
219
+ // return removePageHideListener
220
+ // }
221
+
222
+ // const listenPageFreeze = (callback) => {
223
+ // const removeFreezeListener = listenEvent(document, "freeze", (freezeEvent) => {
224
+ // callback(freezeEvent)
225
+ // })
226
+ // return removeFreezeListener
227
+ // }
228
+
229
+ // const listenPageIsRestored = (callback) => {
230
+ // const removeResumeListener = listenEvent(document, "resume", (resumeEvent) => {
231
+ // removePageshowListener()
232
+ // callback(resumeEvent)
233
+ // })
234
+ // const removePageshowListener = listenEvent(window, "pageshow", (pageshowEvent) => {
235
+ // if (pageshowEvent.persisted === true) {
236
+ // removePageshowListener()
237
+ // removeResumeListener()
238
+ // callback(pageshowEvent)
239
+ // }
240
+ // })
241
+ // return () => {
242
+ // removeResumeListener()
243
+ // removePageshowListener()
244
+ // }
245
+ // }
246
+
247
+ const listenPageUnload = (callback) => {
248
+ const removePageHideListener = listenEvent(
249
+ window,
250
+ "pagehide",
251
+ (pageHideEvent) => {
252
+ if (pageHideEvent.persisted !== true) {
253
+ callback(pageHideEvent);
254
+ }
255
+ },
256
+ );
257
+ return removePageHideListener;
258
+ };
259
+
260
+ const listenEvent = (emitter, event, callback) => {
261
+ emitter.addEventListener(event, callback);
262
+ return () => {
263
+ emitter.removeEventListener(event, callback);
264
+ };
265
+ };
266
+ }
267
+
268
+ let createWebSocketConnection;
269
+ connection_using_websocket: {
270
+ createWebSocketConnection = (
271
+ websocketUrl,
272
+ {
273
+ logs,
274
+ protocols = ["jsenv"],
275
+ useEventsToManageConnection = true,
276
+ retry = false,
277
+ retryAfter = 1000,
278
+ retryMaxAttempt = Infinity,
279
+ retryAllocatedMs = Infinity,
280
+ } = {},
281
+ ) => {
282
+ const connectionManager = createConnectionManager(
283
+ ({ onClosed, onOpen }) => {
284
+ let socket = new WebSocket(websocketUrl, protocols);
285
+ let interval;
286
+ const cleanup = () => {
287
+ if (socket) {
288
+ socket.onerror = null;
289
+ socket.onopen = null;
290
+ socket.onclose = null;
291
+ socket.onmessage = null;
292
+ socket = null;
293
+ clearInterval(interval);
294
+ }
295
+ };
296
+ socket.onerror = () => {
297
+ cleanup();
298
+ onClosed();
299
+ };
300
+ socket.onopen = () => {
301
+ socket.onopen = null;
302
+ onOpen();
303
+ interval = setInterval(() => {
304
+ socket.send('{"type":"ping"}');
305
+ }, 30_000);
306
+ };
307
+ socket.onclose = () => {
308
+ cleanup();
309
+ onClosed();
310
+ };
311
+ socket.onmessage = (messageEvent) => {
312
+ const event = JSON.parse(messageEvent.data);
313
+ eventsManager.triggerCallbacks(event);
314
+ };
315
+ return () => {
316
+ if (socket) {
317
+ socket.close();
318
+ cleanup();
319
+ }
320
+ };
321
+ },
322
+ { logs, retry, retryAfter, retryMaxAttempt, retryAllocatedMs },
323
+ );
324
+ const eventsManager = createEventsManager({
325
+ effect: () => {
326
+ if (useEventsToManageConnection) {
327
+ connectionManager.connect();
328
+ return () => {
329
+ connectionManager.disconnect();
330
+ };
331
+ }
332
+ return null;
333
+ },
334
+ });
335
+
336
+ return {
337
+ readyState: connectionManager.readyState,
338
+ connect: connectionManager.connect,
339
+ disconnect: connectionManager.disconnect,
340
+ listenEvents: (namedCallbacks) => {
341
+ return eventsManager.addCallbacks(namedCallbacks);
342
+ },
343
+ destroy: () => {
344
+ connectionManager.destroy();
345
+ eventsManager.destroy();
346
+ },
347
+ };
348
+ };
349
+ }
350
+
351
+ // let createEventSourceConnection;
352
+ // connection_using_event_source: {
353
+ // createEventSourceConnection = (
354
+ // eventSourceUrl,
355
+ // {
356
+ // withCredentials = true,
357
+ // lastEventId,
358
+ // useEventsToManageConnection = true,
359
+ // retry = false,
360
+ // retryMaxAttempt = Infinity,
361
+ // retryAllocatedMs = Infinity,
362
+ // } = {},
363
+ // ) => {
364
+ // const eventSourceOrigin = new URL(eventSourceUrl).origin;
365
+ // const attemptConnection = ({ onOpen, onClosed }) => {
366
+ // const url = lastEventId
367
+ // ? addLastEventIdIntoUrlSearchParams(eventSourceUrl, lastEventId)
368
+ // : eventSourceUrl;
369
+ // let eventSource = new EventSource(url, { withCredentials });
370
+ // eventSource.onerror = () => {
371
+ // eventSource.onerror = null;
372
+ // eventSource.onopen = null;
373
+ // eventSource.onmessage = null;
374
+ // eventSource = null;
375
+ // onClosed();
376
+ // };
377
+ // eventSource.onopen = () => {
378
+ // eventSource.onopen = null;
379
+ // onOpen();
380
+ // };
381
+ // eventSource.onmessage = (messageEvent) => {
382
+ // if (messageEvent.origin === eventSourceOrigin) {
383
+ // if (messageEvent.lastEventId) {
384
+ // lastEventId = messageEvent.lastEventId;
385
+ // }
386
+ // const event = JSON.parse(messageEvent.data);
387
+ // eventsManager.triggerCallbacks(event);
388
+ // }
389
+ // };
390
+ // return () => {
391
+ // if (eventSource) {
392
+ // eventSource.close();
393
+ // }
394
+ // };
395
+ // };
396
+ // const connectionManager = createConnectionManager(attemptConnection, {
397
+ // retry,
398
+ // retryMaxAttempt,
399
+ // retryAllocatedMs,
400
+ // });
401
+ // const eventsManager = createEventsManager({
402
+ // effect: () => {
403
+ // if (useEventsToManageConnection) {
404
+ // connectionManager.connect();
405
+ // return () => {
406
+ // connectionManager.disconnect();
407
+ // };
408
+ // }
409
+ // return null;
410
+ // },
411
+ // });
412
+
413
+ // return {
414
+ // readyState: connectionManager.readyState,
415
+ // listenEvents: (namedCallbacks) => {
416
+ // return eventsManager.addCallbacks(namedCallbacks);
417
+ // },
418
+ // destroy: () => {
419
+ // connectionManager.destroy();
420
+ // eventsManager.destroy();
421
+ // },
422
+ // };
423
+ // };
424
+
425
+ // const addLastEventIdIntoUrlSearchParams = (url, lastEventId) => {
426
+ // if (url.indexOf("?") === -1) {
427
+ // url += "?";
428
+ // } else {
429
+ // url += "&";
430
+ // }
431
+ // return `${url}last-event-id=${encodeURIComponent(lastEventId)}`;
432
+ // };
433
+ // }
434
+
435
+ const serverEventsInterface = {
436
+ readyState: {},
437
+ connect: () => {},
438
+ disconnect: () => {},
439
+ listenEvents: () => {},
440
+ setup: ({ logs }) => {
441
+ const websocketScheme = self.location.protocol === "https:" ? "wss" : "ws";
442
+ const websocketUrl = `${websocketScheme}://${self.location.host}${self.location.pathname}${self.location.search}`;
443
+ const websocketConnection = createWebSocketConnection(websocketUrl, {
444
+ logs,
445
+ retry: true,
446
+ retryAllocatedMs: 10_000,
447
+ });
448
+
449
+ const { readyState, connect, disconnect, listenEvents } =
450
+ websocketConnection;
451
+
452
+ serverEventsInterface.readyState = readyState;
453
+ serverEventsInterface.connect = connect;
454
+ serverEventsInterface.disconnect = disconnect;
455
+ serverEventsInterface.listenEvents = listenEvents;
456
+
457
+ connect();
458
+ },
15
459
  };
16
- connect();
460
+
461
+ window.__server_events__ = serverEventsInterface;