@marimo-team/frontend 0.14.18-dev36 → 0.14.18-dev38

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 (101) hide show
  1. package/dist/assets/{ConnectedDataExplorerComponent-C8OPWd1i.js → ConnectedDataExplorerComponent-Dv68DrL_.js} +1 -1
  2. package/dist/assets/{ImageComparisonComponent-D78xwx3T.js → ImageComparisonComponent-B1uRvjCG.js} +1 -1
  3. package/dist/assets/{VegaLite-CBvhMn_r.js → VegaLite-DcJJGHdT.js} +1 -1
  4. package/dist/assets/{_baseEach-Bp57hest.js → _baseEach-DuV3zbFg.js} +1 -1
  5. package/dist/assets/_baseMap-CXKOjduW.js +1 -0
  6. package/dist/assets/{_baseUniq-Dc93gwgs.js → _baseUniq-B4fO5WxV.js} +1 -1
  7. package/dist/assets/{_createAggregator-DL75L2j7.js → _createAggregator-B1gGJnz5.js} +1 -1
  8. package/dist/assets/{any-language-editor-C2lbkVMC.js → any-language-editor-gUm8Pr5k.js} +1 -1
  9. package/dist/assets/{architectureDiagram-SUXI7LT5-Cf_zm3ra.js → architectureDiagram-SUXI7LT5-D8JW0vTZ.js} +1 -1
  10. package/dist/assets/{blockDiagram-6J76NXCF-DQxNzyQp.js → blockDiagram-6J76NXCF-pje0e_9-.js} +1 -1
  11. package/dist/assets/{c4Diagram-6F6E4RAY-CBI6dOsR.js → c4Diagram-6F6E4RAY-pRJXc-X6.js} +1 -1
  12. package/dist/assets/channel-DSfjdvRx.js +1 -0
  13. package/dist/assets/{chunk-353BL4L5-7rsTGLoE.js → chunk-353BL4L5-DWP0EAjK.js} +1 -1
  14. package/dist/assets/{chunk-67H74DCK-DEfPKYcN.js → chunk-67H74DCK-CxePEeQq.js} +1 -1
  15. package/dist/assets/{chunk-AACKK3MU-BmX0ClsR.js → chunk-AACKK3MU-CyndqHmU.js} +1 -1
  16. package/dist/assets/{chunk-BFAMUDN2-C_ssuRFB.js → chunk-BFAMUDN2-BE9bwlib.js} +1 -1
  17. package/dist/assets/{chunk-E2GYISFI-SbTvBHWD.js → chunk-E2GYISFI-B85SWyoP.js} +1 -1
  18. package/dist/assets/{chunk-OW32GOEJ-DqkzVAPz.js → chunk-OW32GOEJ-C5Ag_xqO.js} +1 -1
  19. package/dist/assets/{chunk-SKB7J2MH-D47zuUjI.js → chunk-SKB7J2MH-DkUhr5YQ.js} +1 -1
  20. package/dist/assets/{chunk-SZ463SBG-DgTD1nXW.js → chunk-SZ463SBG-Bz17SFYY.js} +1 -1
  21. package/dist/assets/{circle-play-BH7xRyKB.js → circle-play-BgNmoXvo.js} +1 -1
  22. package/dist/assets/classDiagram-M3E45YP4-W7ZwJ9Nk.js +1 -0
  23. package/dist/assets/classDiagram-v2-YAWTLIQI-W7ZwJ9Nk.js +1 -0
  24. package/dist/assets/clone-D0s-H6Md.js +1 -0
  25. package/dist/assets/{compile-DXxN2AUj.js → compile-CHyG-xBK.js} +1 -1
  26. package/dist/assets/{dagre-JOIXM2OF-788QcFe0.js → dagre-JOIXM2OF-tScjgBWM.js} +1 -1
  27. package/dist/assets/{data-grid-overlay-editor-WWBnkboI.js → data-grid-overlay-editor-CI501ZK0.js} +1 -1
  28. package/dist/assets/{diagram-5UYTHUR4-lzkrT1_y.js → diagram-5UYTHUR4-1UwgEQLe.js} +1 -1
  29. package/dist/assets/{diagram-VMROVX33-Bk8f7S1u.js → diagram-VMROVX33-hKKw3I1i.js} +1 -1
  30. package/dist/assets/{diagram-ZTM2IBQH-BxLgHpva.js → diagram-ZTM2IBQH-CyEG2YHp.js} +1 -1
  31. package/dist/assets/{edit-page-B2hC8W7Q.js → edit-page-D9vV7W7m.js} +4 -4
  32. package/dist/assets/{erDiagram-3M52JZNH-BYKNMZP8.js → erDiagram-3M52JZNH-a-tNhsYp.js} +1 -1
  33. package/dist/assets/{flowDiagram-KYDEHFYC-CQbi_VzA.js → flowDiagram-KYDEHFYC-CnZqSO3t.js} +1 -1
  34. package/dist/assets/{ganttDiagram-EK5VF46D-k6VKsj3J.js → ganttDiagram-EK5VF46D-6Pfp7XZd.js} +1 -1
  35. package/dist/assets/{gitGraphDiagram-GW3U2K7C-DMKQY40Z.js → gitGraphDiagram-GW3U2K7C-CD6KQaJF.js} +1 -1
  36. package/dist/assets/{glide-data-editor-D9OIoerO.js → glide-data-editor-Bk9UyPiz.js} +4 -4
  37. package/dist/assets/{graph-B--PlE3U.js → graph-BLBzFGRL.js} +1 -1
  38. package/dist/assets/{home-page-D3f4VB2_.js → home-page-Dtk3jnN0.js} +1 -1
  39. package/dist/assets/{index-DwMjE8U1.js → index-BMYfIFnR.js} +1 -1
  40. package/dist/assets/{index-2ck97tRr.js → index-BVeys4As.js} +1 -1
  41. package/dist/assets/{index-DorUubyB.js → index-BZMexvZ6.js} +1 -1
  42. package/dist/assets/{index-DoSPRUKa.js → index-C4P8DJgN.js} +1 -1
  43. package/dist/assets/{index-DLeVWM_j.js → index-CA2h-g7e.js} +1 -1
  44. package/dist/assets/{index-DOQuxMxe.js → index-CCBKzLLu.js} +1 -1
  45. package/dist/assets/{index-fffF5hyA.js → index-CFCxalSV.js} +120 -120
  46. package/dist/assets/{index-rwSg8XkS.js → index-CSP0KaW6.js} +1 -1
  47. package/dist/assets/{index-Cotvreue.js → index-Cdq0JLN7.js} +1 -1
  48. package/dist/assets/{index-Bi3R2u0F.js → index-CofDTD9Q.js} +1 -1
  49. package/dist/assets/{index-DAWFA-yG.js → index-D1i6-Vzt.js} +1 -1
  50. package/dist/assets/{index-O9oIU7eC.js → index-DEhXWjAF.js} +1 -1
  51. package/dist/assets/{index-DoyRX0dO.js → index-DLvVH5yg.js} +1 -1
  52. package/dist/assets/{index-Cl7WcwXY.js → index-DVotKDCm.js} +1 -1
  53. package/dist/assets/{index-DH0GFdbS.js → index-DfkIq4yn.js} +1 -1
  54. package/dist/assets/{index-bxSO2HBZ.js → index-DiD7NRwC.js} +1 -1
  55. package/dist/assets/{index-CfxRZRRd.js → index-Dke4Ikso.js} +1 -1
  56. package/dist/assets/{index-oS3Z_dbb.js → index-FRgaLm_h.js} +1 -1
  57. package/dist/assets/{index-Cr-iILfd.js → index-IRmeC8mO.js} +1 -1
  58. package/dist/assets/{index-CQ4WXKRW.js → index-lRvedUef.js} +1 -1
  59. package/dist/assets/infoDiagram-LHK5PUON-BcKRYZqP.js +2 -0
  60. package/dist/assets/{journeyDiagram-EWQZEKCU-C0x4ScVq.js → journeyDiagram-EWQZEKCU-BJDGTPdN.js} +1 -1
  61. package/dist/assets/{kanban-definition-ZSS6B67P-CPUCHzVH.js → kanban-definition-ZSS6B67P-CvXSD86T.js} +1 -1
  62. package/dist/assets/{layout-D37rUtsH.js → layout-CAJqQFqW.js} +1 -1
  63. package/dist/assets/{linear-D2od76F0.js → linear-B1-iCo54.js} +1 -1
  64. package/dist/assets/{links-DYAVS2b2.js → links-Df4dtLc_.js} +1 -1
  65. package/dist/assets/{mermaid-Co0X0ppY.js → mermaid-CoTltW6T.js} +4 -4
  66. package/dist/assets/{min-CxjLn3lS.js → min-CAtH1e7k.js} +1 -1
  67. package/dist/assets/{mindmap-definition-6CBA2TL7-B6E8cHyB.js → mindmap-definition-6CBA2TL7-8_3hl_9G.js} +1 -1
  68. package/dist/assets/{number-overlay-editor-DxC3kyNO.js → number-overlay-editor-_U6Bi7tP.js} +1 -1
  69. package/dist/assets/{pieDiagram-NIOCPIFQ-CfPABeMA.js → pieDiagram-NIOCPIFQ-5Piswj_j.js} +1 -1
  70. package/dist/assets/{quadrantDiagram-2OG54O6I-CwUMrCPC.js → quadrantDiagram-2OG54O6I-B-eCUAoN.js} +1 -1
  71. package/dist/assets/{react-plotly-DlVC_dj1.js → react-plotly-4mSeoo5U.js} +1 -1
  72. package/dist/assets/{requirementDiagram-QOLK2EJ7-C6jYnO5-.js → requirementDiagram-QOLK2EJ7-DcePxcNR.js} +1 -1
  73. package/dist/assets/{run-page-C6ABwpyl.js → run-page-CojJ7qSs.js} +1 -1
  74. package/dist/assets/{sankeyDiagram-4UZDY2LN-CVGAel0O.js → sankeyDiagram-4UZDY2LN-CFtqqzJ-.js} +1 -1
  75. package/dist/assets/{sequenceDiagram-SKLFT4DO-CtoWu3R6.js → sequenceDiagram-SKLFT4DO-B2b0ayzr.js} +1 -1
  76. package/dist/assets/{slides-component-CBgFvOS6.js → slides-component-Bo-bOPD4.js} +1 -1
  77. package/dist/assets/{sortBy-CHbZ6Ez9.js → sortBy-CQ7cYGOi.js} +1 -1
  78. package/dist/assets/{stateDiagram-MI5ZYTHO-CQdObm69.js → stateDiagram-MI5ZYTHO-CraGSGCe.js} +1 -1
  79. package/dist/assets/stateDiagram-v2-5AN5P6BG-B6V5_20O.js +1 -0
  80. package/dist/assets/{storage-DMEGIdds.js → storage-B7zCO6St.js} +3 -3
  81. package/dist/assets/{terminal-DG0SsiRU.js → terminal-tKrSa7wD.js} +1 -1
  82. package/dist/assets/{time-y7EyvZDn.js → time-DfceXfii.js} +1 -1
  83. package/dist/assets/{timeline-definition-MYPXXCX6-CKqyCmyc.js → timeline-definition-MYPXXCX6-mETqJEkh.js} +1 -1
  84. package/dist/assets/{tracing-82RjvJAZ.js → tracing-Df7FGhtp.js} +2 -2
  85. package/dist/assets/{trash-DLmP1wkr.js → trash-D_witDuD.js} +1 -1
  86. package/dist/assets/{treemap-75Q7IDZK-D8nmNQUP.js → treemap-75Q7IDZK-2zY68G8S.js} +1 -1
  87. package/dist/assets/{vega-component-BB9UqYwO.js → vega-component-BriH_8ZE.js} +1 -1
  88. package/dist/assets/{xychartDiagram-H2YORKM3-DItXHD9N.js → xychartDiagram-H2YORKM3-CBxGxXLd.js} +1 -1
  89. package/dist/index.html +1 -1
  90. package/package.json +1 -1
  91. package/src/core/runtime/__tests__/config.test.ts +12 -0
  92. package/src/core/runtime/config.ts +6 -1
  93. package/src/core/static/__tests__/files.test.ts +311 -0
  94. package/src/core/static/files.ts +35 -33
  95. package/dist/assets/_baseMap-D0odIxUE.js +0 -1
  96. package/dist/assets/channel-COf2II2e.js +0 -1
  97. package/dist/assets/classDiagram-M3E45YP4-DLy_0M38.js +0 -1
  98. package/dist/assets/classDiagram-v2-YAWTLIQI-DLy_0M38.js +0 -1
  99. package/dist/assets/clone-CLl10UdK.js +0 -1
  100. package/dist/assets/infoDiagram-LHK5PUON-CkfJu9Qh.js +0 -2
  101. package/dist/assets/stateDiagram-v2-5AN5P6BG-C3Ibkepp.js +0 -1
@@ -4,6 +4,7 @@
4
4
  import http from "node:http";
5
5
  import { afterAll, beforeAll, describe, expect, it, vi } from "vitest";
6
6
  import { createLoader } from "@/plugins/impl/vega/vega-loader";
7
+ import { Functions } from "@/utils/functions";
7
8
  import type { DataURLString } from "@/utils/json/base64";
8
9
  import { patchFetch, patchVegaLoader } from "../files";
9
10
 
@@ -83,6 +84,104 @@ describe("patchFetch", () => {
83
84
  expect(text).toBe("hello,world\n");
84
85
  }
85
86
  });
87
+
88
+ it("should handle file:// URLs with @file/ paths", async () => {
89
+ const virtualFiles = {
90
+ "/@file/local-data.txt":
91
+ "data:text/plain;base64,TG9jYWwgZmlsZSBkYXRh" as DataURLString,
92
+ };
93
+
94
+ const unpatch = patchFetch(virtualFiles);
95
+
96
+ const response = await window.fetch(
97
+ "file:///Users/test/@file/local-data.txt",
98
+ );
99
+ const text = await response.text();
100
+
101
+ expect(text).toBe("Local file data");
102
+ expect(response.headers.get("Content-Type")).toBe("text/plain");
103
+
104
+ unpatch();
105
+ });
106
+
107
+ it("should handle blob: base URIs correctly", async () => {
108
+ // Mock document.baseURI to simulate blob: protocol
109
+ const originalBaseURI = document.baseURI;
110
+ Object.defineProperty(document, "baseURI", {
111
+ value: "blob:https://example.com/uuid",
112
+ configurable: true,
113
+ });
114
+
115
+ const virtualFiles = {
116
+ "/@file/blob-test.json":
117
+ "data:application/json;base64,eyJ0ZXN0IjogdHJ1ZX0=" as DataURLString,
118
+ };
119
+
120
+ patchFetch(virtualFiles);
121
+
122
+ const response = await window.fetch("/@file/blob-test.json");
123
+ const text = await response.text();
124
+
125
+ expect(text).toBe('{"test": true}');
126
+ expect(response.headers.get("Content-Type")).toBe("application/json");
127
+
128
+ // Restore original baseURI
129
+ Object.defineProperty(document, "baseURI", {
130
+ value: originalBaseURI,
131
+ configurable: true,
132
+ });
133
+ });
134
+
135
+ it("should handle various content types", async () => {
136
+ const virtualFiles = {
137
+ "/@file/test.csv": "data:text/csv;base64,YSxiLGMK" as DataURLString,
138
+ "/@file/test.json": "data:application/json;base64,e30K" as DataURLString,
139
+ "/@file/test.txt": "data:text/plain;base64,dGVzdA==" as DataURLString,
140
+ "/@file/test.bin":
141
+ "data:application/octet-stream;base64,AAECAwQ=" as DataURLString,
142
+ };
143
+
144
+ patchFetch(virtualFiles);
145
+
146
+ const testCases = [
147
+ { file: "/@file/test.csv", expectedType: "text/csv" },
148
+ { file: "/@file/test.json", expectedType: "application/json" },
149
+ { file: "/@file/test.txt", expectedType: "text/plain" },
150
+ { file: "/@file/test.bin", expectedType: "application/octet-stream" },
151
+ ];
152
+
153
+ for (const { file, expectedType } of testCases) {
154
+ const response = await window.fetch(file);
155
+ expect(response.headers.get("Content-Type")).toBe(expectedType);
156
+ }
157
+ });
158
+
159
+ it("should handle data: URLs directly without processing", async () => {
160
+ const virtualFiles = {};
161
+ patchFetch(virtualFiles);
162
+
163
+ const dataUrl = "data:text/plain;base64,SGVsbG8gV29ybGQ=";
164
+ const response = await window.fetch(dataUrl);
165
+ const text = await response.text();
166
+
167
+ expect(text).toBe("Hello World");
168
+ });
169
+
170
+ it("should handle error cases gracefully", async () => {
171
+ const virtualFiles = {};
172
+ const unpatch = patchFetch(virtualFiles);
173
+
174
+ // Mock Logger.error to avoid console output during tests
175
+ const loggerSpy = vi
176
+ .spyOn(console, "error")
177
+ .mockImplementation(Functions.NOOP);
178
+
179
+ // This should fallback to original fetch and potentially fail
180
+ await expect(window.fetch("invalid://url")).rejects.toThrow();
181
+
182
+ unpatch();
183
+ loggerSpy.mockRestore();
184
+ });
86
185
  });
87
186
 
88
187
  describe("patchVegaLoader - loader.http", () => {
@@ -180,4 +279,216 @@ describe("patchVegaLoader - loader.load", () => {
180
279
  await expect(loader.load("/non-existent-file.json")).rejects.toThrow();
181
280
  unpatch();
182
281
  });
282
+
283
+ it("should handle file:// URLs with @file/ paths in loader.load", async () => {
284
+ const virtualFiles = {
285
+ "/@file/vega-data.json":
286
+ "data:application/json;base64,eyJ2YWx1ZXMiOiBbMSwgMiwgM119" as DataURLString,
287
+ };
288
+
289
+ const loader = createLoader();
290
+ const unpatch = patchVegaLoader(loader, virtualFiles);
291
+
292
+ try {
293
+ const content = await loader.load("file:///path/to/@file/vega-data.json");
294
+ expect(content).toBe('{"values": [1, 2, 3]}');
295
+ } catch (error) {
296
+ // If it falls back to original loader and fails, that's expected for file:// URLs
297
+ // The important thing is that the virtual file lookup was attempted
298
+ expect(error).toBeDefined();
299
+ }
300
+
301
+ unpatch();
302
+ });
303
+
304
+ it("should pass files parameter correctly to maybeGetVirtualFile in loader.load", async () => {
305
+ // This test ensures the bug fix where files parameter was missing
306
+ const virtualFiles = {
307
+ "/test-file.json":
308
+ "data:application/json;base64,eyJmaXhlZCI6IHRydWV9" as DataURLString,
309
+ };
310
+
311
+ const loader = createLoader();
312
+ const unpatch = patchVegaLoader(loader, virtualFiles);
313
+ const content = await loader.load("/test-file.json");
314
+ unpatch();
315
+
316
+ expect(content).toBe('{"fixed": true}');
317
+ });
318
+
319
+ it("should handle different URL patterns in loader.load", async () => {
320
+ const virtualFiles = {
321
+ "/@file/pattern-test.json":
322
+ "data:application/json;base64,eyJwYXR0ZXJuIjogInRlc3QifQ==" as DataURLString,
323
+ };
324
+
325
+ const loader = createLoader();
326
+ const unpatch = patchVegaLoader(loader, virtualFiles);
327
+
328
+ // Test URL patterns that should resolve to the same virtual file
329
+ const testUrls = [
330
+ "/@file/pattern-test.json",
331
+ "./@file/pattern-test.json",
332
+ "http://example.com/@file/pattern-test.json",
333
+ ];
334
+
335
+ for (const url of testUrls) {
336
+ const content = await loader.load(url);
337
+ expect(content).toBe('{"pattern": "test"}');
338
+ }
339
+
340
+ // Test file:// URL separately since it might fallback
341
+ try {
342
+ const content = await loader.load(
343
+ "file:///local/path/@file/pattern-test.json",
344
+ );
345
+ expect(content).toBe('{"pattern": "test"}');
346
+ } catch (error) {
347
+ // Expected if it falls back to original loader
348
+ expect(error).toBeDefined();
349
+ }
350
+
351
+ unpatch();
352
+ });
353
+ });
354
+
355
+ describe("maybeGetVirtualFile utility function", () => {
356
+ it("should handle URLs without leading dots correctly", async () => {
357
+ const virtualFiles = {
358
+ "/file.txt": "data:text/plain;base64,dGVzdA==" as DataURLString,
359
+ "file.txt": "data:text/plain;base64,dGVzdA==" as DataURLString,
360
+ };
361
+
362
+ patchFetch(virtualFiles);
363
+
364
+ // Both should work
365
+ const response1 = await window.fetch("./file.txt");
366
+ const response2 = await window.fetch("/file.txt");
367
+
368
+ const text1 = await response1.text();
369
+ const text2 = await response2.text();
370
+
371
+ expect(text1).toBe("test");
372
+ expect(text2).toBe("test");
373
+ });
374
+
375
+ it("should handle complex file:// URLs with nested paths", async () => {
376
+ const virtualFiles = {
377
+ "/@file/nested/data.json":
378
+ "data:application/json;base64,eyJuZXN0ZWQiOiB0cnVlfQ==" as DataURLString,
379
+ };
380
+
381
+ const unpatch = patchFetch(virtualFiles);
382
+
383
+ const response = await window.fetch(
384
+ "file:///Users/project/deep/path/@file/nested/data.json",
385
+ );
386
+ const text = await response.text();
387
+
388
+ expect(text).toBe('{"nested": true}');
389
+
390
+ unpatch();
391
+ });
392
+
393
+ it("should handle URLs when @file/ is not found in file:// URLs", async () => {
394
+ const virtualFiles = {
395
+ "/@file/test.txt": "data:text/plain;base64,dGVzdA==" as DataURLString,
396
+ };
397
+
398
+ const unpatch = patchFetch(virtualFiles);
399
+
400
+ // This file:// URL doesn't contain @file/, so it should fallback to original fetch
401
+ await expect(
402
+ window.fetch("file:///simple/path/test.txt"),
403
+ ).rejects.toThrow();
404
+
405
+ unpatch();
406
+ });
407
+ });
408
+
409
+ describe("error handling and edge cases", () => {
410
+ it("should restore original functions after unpatch", async () => {
411
+ const originalFetch = window.fetch;
412
+ const loader = createLoader();
413
+
414
+ const unpatchFetch = patchFetch({});
415
+ const unpatchLoader = patchVegaLoader(loader, {});
416
+
417
+ // Functions should be patched
418
+ expect(window.fetch).not.toBe(originalFetch);
419
+
420
+ // Test that the patched functions work
421
+ const virtualFiles = {
422
+ "/@file/test.txt": "data:text/plain;base64,dGVzdA==" as DataURLString,
423
+ };
424
+
425
+ // Re-patch with test data
426
+ unpatchFetch();
427
+ unpatchLoader();
428
+
429
+ const unpatchFetch2 = patchFetch(virtualFiles);
430
+ const unpatchLoader2 = patchVegaLoader(loader, virtualFiles);
431
+
432
+ // Test functionality works
433
+ const response = await window.fetch("/@file/test.txt");
434
+ const text = await response.text();
435
+ expect(text).toBe("test");
436
+
437
+ const content = await loader.load("/@file/test.txt");
438
+ expect(content).toBe("test");
439
+
440
+ unpatchFetch2();
441
+ unpatchLoader2();
442
+
443
+ // Functions should be restored
444
+ expect(window.fetch).toBe(originalFetch);
445
+
446
+ // Test that the loader functions are functional (they should work normally)
447
+ try {
448
+ await loader.load("http://example.com/test.json");
449
+ } catch (error) {
450
+ // Expected to fail for non-existent URLs, but the function should be callable
451
+ expect(error).toBeDefined();
452
+ }
453
+ });
454
+
455
+ it("should handle Request objects in patchFetch", async () => {
456
+ const virtualFiles = {
457
+ "/@file/request-test.txt":
458
+ "data:text/plain;base64,UmVxdWVzdCB0ZXN0" as DataURLString,
459
+ };
460
+
461
+ const unpatch = patchFetch(virtualFiles);
462
+
463
+ // Use a full URL for the Request constructor
464
+ const request = new Request("http://example.com/@file/request-test.txt");
465
+ const response = await window.fetch(request);
466
+ const text = await response.text();
467
+
468
+ expect(text).toBe("Request test");
469
+
470
+ unpatch();
471
+ });
472
+
473
+ it("should handle malformed URLs gracefully", async () => {
474
+ const virtualFiles = {};
475
+ const unpatch = patchFetch(virtualFiles);
476
+
477
+ // Mock Logger.error to avoid test output
478
+ const loggerSpy = vi
479
+ .spyOn(console, "error")
480
+ .mockImplementation(Functions.NOOP);
481
+
482
+ // This should catch the error and fallback to original fetch
483
+ try {
484
+ await window.fetch("not-a-valid-url");
485
+ // If it doesn't throw, that's also fine (fallback behavior)
486
+ } catch (error) {
487
+ // Expected behavior - invalid URLs should be handled gracefully
488
+ expect(error).toBeDefined();
489
+ }
490
+
491
+ unpatch();
492
+ loggerSpy.mockRestore();
493
+ });
183
494
  });
@@ -24,20 +24,15 @@ export function patchFetch(
24
24
  }
25
25
 
26
26
  try {
27
- const url =
28
- urlString.startsWith("/") || urlString.startsWith("./")
29
- ? new URL(urlString, window.location.origin)
30
- : new URL(urlString);
31
-
32
- const filePath = url.pathname;
33
- if (files[filePath]) {
34
- const base64 = files[filePath];
27
+ const vfile = maybeGetVirtualFile(urlString, files);
28
+ if (vfile) {
29
+ const base64 = vfile;
35
30
  // Convert data URL to blob
36
31
  const response = await originalFetch(base64);
37
32
  const blob = await response.blob();
38
33
  return new Response(blob, {
39
34
  headers: {
40
- "Content-Type": getContentType(filePath),
35
+ "Content-Type": getContentType(urlString),
41
36
  },
42
37
  });
43
38
  }
@@ -77,30 +72,8 @@ export function patchVegaLoader(
77
72
  const originalHttp = loader.http.bind(loader);
78
73
  const originalLoad = loader.load.bind(loader);
79
74
 
80
- function maybeGetVirtualFile(url: string): string | undefined {
81
- const pathname = new URL(url, document.baseURI).pathname;
82
-
83
- // If if the URL starts with file://, then using the document.baseURI
84
- // will not work. In this case, should just chop off from /@file/...
85
- if (url.startsWith("file://")) {
86
- const indexOfFile = url.indexOf("/@file/");
87
- if (indexOfFile !== -1) {
88
- url = files[url.slice(indexOfFile)];
89
- }
90
- }
91
-
92
- // Few variations to grab the URL.
93
- // This can happen if a static file was open at file:// or https://
94
- return (
95
- files[url] ||
96
- files[withoutLeadingDot(url)] ||
97
- files[pathname] ||
98
- files[withoutLeadingDot(pathname)]
99
- );
100
- }
101
-
102
75
  loader.http = async (url: string) => {
103
- const vfile = maybeGetVirtualFile(url);
76
+ const vfile = maybeGetVirtualFile(url, files);
104
77
  if (vfile) {
105
78
  // If the file is a virtual file, fetch it
106
79
  return await window.fetch(vfile).then((r) => r.text());
@@ -119,7 +92,7 @@ export function patchVegaLoader(
119
92
  };
120
93
 
121
94
  loader.load = async (url: string) => {
122
- const vfile = maybeGetVirtualFile(url);
95
+ const vfile = maybeGetVirtualFile(url, files);
123
96
  if (vfile) {
124
97
  // If the file is a virtual file, fetch it
125
98
  return await window.fetch(vfile).then((r) => r.text());
@@ -146,3 +119,32 @@ export function patchVegaLoader(
146
119
  function withoutLeadingDot(path: string): string {
147
120
  return path.startsWith(".") ? path.slice(1) : path;
148
121
  }
122
+
123
+ function maybeGetVirtualFile(
124
+ url: string,
125
+ files: StaticVirtualFiles,
126
+ ): string | undefined {
127
+ let base = document.baseURI;
128
+ if (base.startsWith("blob:")) {
129
+ base = base.replace("blob:", "");
130
+ }
131
+ const pathname = new URL(url, base).pathname;
132
+
133
+ // If if the URL starts with file://, then using the document.baseURI
134
+ // will not work. In this case, should just chop off from /@file/...
135
+ if (url.startsWith("file://")) {
136
+ const indexOfFile = url.indexOf("/@file/");
137
+ if (indexOfFile !== -1) {
138
+ url = url.slice(indexOfFile);
139
+ }
140
+ }
141
+
142
+ // Few variations to grab the URL.
143
+ // This can happen if a static file was open at file:// or https://
144
+ return (
145
+ files[url] ||
146
+ files[withoutLeadingDot(url)] ||
147
+ files[pathname] ||
148
+ files[withoutLeadingDot(pathname)]
149
+ );
150
+ }
@@ -1 +0,0 @@
1
- import{b as m}from"./_baseEach-Bp57hest.js";import{x as s}from"./index-fffF5hyA.js";function e(r,o){var a=-1,t=s(r)?Array(r.length):[];return m(r,function(n,f,i){t[++a]=o(n,f,i)}),t}export{e as b};
@@ -1 +0,0 @@
1
- import{U as s,C as o}from"./mermaid-Co0X0ppY.js";const n=(a,r)=>s.lang.round(o.parse(a)[r]);export{n as c};
@@ -1 +0,0 @@
1
- import{s as a,c as s,a as t,C as o}from"./chunk-SZ463SBG-DgTD1nXW.js";import{_ as e}from"./mermaid-Co0X0ppY.js";import"./transform-B8bpuzxV.js";import"./chunk-E2GYISFI-SbTvBHWD.js";import"./chunk-BFAMUDN2-C_ssuRFB.js";import"./chunk-SKB7J2MH-D47zuUjI.js";import"./index-fffF5hyA.js";import"./step-BwsUM5iJ.js";import"./timer-BwIYMJWC.js";var i={parser:t,get db(){return new o},renderer:s,styles:a,init:e(r=>{r.class||(r.class={}),r.class.arrowMarkerAbsolute=r.arrowMarkerAbsolute},"init")};export{i as diagram};
@@ -1 +0,0 @@
1
- import{s as a,c as s,a as t,C as o}from"./chunk-SZ463SBG-DgTD1nXW.js";import{_ as e}from"./mermaid-Co0X0ppY.js";import"./transform-B8bpuzxV.js";import"./chunk-E2GYISFI-SbTvBHWD.js";import"./chunk-BFAMUDN2-C_ssuRFB.js";import"./chunk-SKB7J2MH-D47zuUjI.js";import"./index-fffF5hyA.js";import"./step-BwsUM5iJ.js";import"./timer-BwIYMJWC.js";var i={parser:t,get db(){return new o},renderer:s,styles:a,init:e(r=>{r.class||(r.class={}),r.class.arrowMarkerAbsolute=r.arrowMarkerAbsolute},"init")};export{i as diagram};
@@ -1 +0,0 @@
1
- import{b as n}from"./_baseUniq-Dc93gwgs.js";function o(r){return n(r,4)}export{o as c};
@@ -1,2 +0,0 @@
1
- import{_ as a,l as i,I as s,d as p,K as n}from"./mermaid-Co0X0ppY.js";import{p as m}from"./treemap-75Q7IDZK-D8nmNQUP.js";import"./index-fffF5hyA.js";import"./transform-B8bpuzxV.js";import"./timer-BwIYMJWC.js";import"./step-BwsUM5iJ.js";import"./_baseEach-Bp57hest.js";import"./_baseUniq-Dc93gwgs.js";import"./min-CxjLn3lS.js";import"./_baseMap-D0odIxUE.js";import"./clone-CLl10UdK.js";import"./_createAggregator-DL75L2j7.js";var d={parse:a(async r=>{const t=await m("info",r);i.debug(t)},"parse")},g={version:n.version+""},v={parser:d,db:{getVersion:a(()=>g.version,"getVersion")},renderer:{draw:a((r,t,o)=>{i.debug(`rendering info diagram
2
- `+r);const e=s(t);p(e,100,400,!0),e.append("g").append("text").attr("x",100).attr("y",40).attr("class","version").attr("font-size",32).style("text-anchor","middle").text(`v${o}`)},"draw")}};export{v as diagram};
@@ -1 +0,0 @@
1
- import{s as t,b as a,a as e,S as o}from"./chunk-OW32GOEJ-DqkzVAPz.js";import{_ as s}from"./mermaid-Co0X0ppY.js";import"./transform-B8bpuzxV.js";import"./chunk-BFAMUDN2-C_ssuRFB.js";import"./chunk-SKB7J2MH-D47zuUjI.js";import"./index-fffF5hyA.js";import"./step-BwsUM5iJ.js";import"./timer-BwIYMJWC.js";var i={parser:e,get db(){return new o(2)},renderer:a,styles:t,init:s(r=>{r.state||(r.state={}),r.state.arrowMarkerAbsolute=r.arrowMarkerAbsolute},"init")};export{i as diagram};