module-tsx 0.0.4 → 0.1.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.
package/README.md CHANGED
@@ -96,6 +96,9 @@ npx skills add yieldray/module-tsx
96
96
  <!-- ESM -->
97
97
  <script type="module" src="https://esm.sh/module-tsx"></script>
98
98
 
99
+ <!-- ESM (DEV mode) -->
100
+ <script type="module" src="https://esm.sh/module-tsx/dev"></script>
101
+
99
102
  <!-- ESM (self-contained, no external dependencies) -->
100
103
  <script
101
104
  type="module"
@@ -13,7 +13,7 @@ function warn(message, ...args) {
13
13
  console.warn(`[module-tsx] ${message}`, ...args);
14
14
  }
15
15
  //#endregion
16
- //#region src/importmap.ts
16
+ //#region src/import-map.ts
17
17
  var ImportMap = class {
18
18
  imports;
19
19
  scopes;
@@ -307,14 +307,20 @@ function cssToModule(cssString, prefix) {
307
307
  //#endregion
308
308
  //#region src/network.ts
309
309
  async function fetchResponse(input, init) {
310
- const res = await fetch(input, init);
311
- if (!res.ok) throw new ModuleTSXError(`Failed to fetch resource ${res.url}: ${res.status}`);
310
+ const url = input instanceof Request ? input.url : String(input);
311
+ let res;
312
+ try {
313
+ res = await fetch(input, init);
314
+ } catch (cause) {
315
+ throw new ModuleTSXError(`Failed to fetch module ${url}: Network error`, { cause });
316
+ }
317
+ if (!res.ok) throw new ModuleTSXError(`Failed to fetch module ${url}: ${res.status} ${res.statusText}`);
312
318
  return res;
313
319
  }
314
320
  //#endregion
315
321
  //#region src/specifier.ts
316
322
  function isBareSpecifier(specifier) {
317
- if (specifier.match(/^\.*\//)) return false;
323
+ if (isRelativeSpecifier(specifier)) return false;
318
324
  try {
319
325
  new URL(specifier);
320
326
  return false;
@@ -323,7 +329,7 @@ function isBareSpecifier(specifier) {
323
329
  }
324
330
  }
325
331
  function isRelativeSpecifier(specifier) {
326
- return specifier.startsWith(".") || specifier.startsWith("/");
332
+ return specifier.startsWith("./") || specifier.startsWith("../") || specifier.startsWith("/");
327
333
  }
328
334
  function collectSpecifiers(sourceFile) {
329
335
  const set = /* @__PURE__ */ new Set();
@@ -416,12 +422,17 @@ var SourceTransformTracker = class {
416
422
  sourceMap = /* @__PURE__ */ new Map();
417
423
  inFlightSourceMap = /* @__PURE__ */ new Map();
418
424
  blobMap = /* @__PURE__ */ new Map();
425
+ originalSourceMap = /* @__PURE__ */ new Map();
419
426
  get(sourceType, sourceUrl) {
420
427
  return this.sourceMap.get(this.getSourceKey(sourceType, sourceUrl));
421
428
  }
422
- set(sourceType, sourceUrl, blobUrl) {
429
+ set(sourceType, sourceUrl, blobUrl, originalSource) {
423
430
  this.sourceMap.set(this.getSourceKey(sourceType, sourceUrl), blobUrl);
424
431
  this.blobMap.set(blobUrl, sourceUrl);
432
+ if (originalSource != null) this.originalSourceMap.set(blobUrl, originalSource);
433
+ }
434
+ getOriginalSource(blobUrl) {
435
+ return this.originalSourceMap.get(blobUrl);
425
436
  }
426
437
  isInFlight(sourceType, sourceUrl) {
427
438
  return this.inFlightSourceMap.has(this.getSourceKey(sourceType, sourceUrl));
@@ -505,6 +516,14 @@ var ModuleTSX = class extends EventTarget {
505
516
  addImportMap(newImportMap) {
506
517
  ImportMap.merge(this.importMap, newImportMap, this.resolvedModuleSet);
507
518
  }
519
+ /** Resolve a blob URL back to its original source URL. Returns undefined if not found. */
520
+ getSourceUrlByBlob(blobUrl) {
521
+ return this.sourceTracker.getSourceUrlByBlob(blobUrl);
522
+ }
523
+ /** Get the original source code that was compiled into a given blob URL. */
524
+ getOriginalSource(blobUrl) {
525
+ return this.sourceTracker.getOriginalSource(blobUrl);
526
+ }
508
527
  emit(type, detail) {
509
528
  this.dispatchEvent(new CustomEvent(type, { detail }));
510
529
  this.dispatchEvent(new CustomEvent("*", { detail: {
@@ -553,7 +572,7 @@ var ModuleTSX = class extends EventTarget {
553
572
  const code = `import.meta.url=${JSON.stringify(sourceUrl)};\n` + await loader(sourceUrl, sourceCode);
554
573
  const blob = new Blob([code], { type: "text/javascript" });
555
574
  const blobUrl = URL.createObjectURL(blob);
556
- this.sourceTracker.set(sourceType, sourceUrl, blobUrl);
575
+ this.sourceTracker.set(sourceType, sourceUrl, blobUrl, sourceCode);
557
576
  return blobUrl;
558
577
  });
559
578
  }
@@ -654,7 +673,7 @@ async function sideEffect() {
654
673
  for (const s of Array.from(document.querySelectorAll(`script[type="${TYPE_ATTRIBUTE_VALUE}"]`))) {
655
674
  const script = s;
656
675
  if (!script.async && script.defer) warn(`script with type="${TYPE_ATTRIBUTE_VALUE}" does not support defer attribute. Use async or no attribute instead.`);
657
- for (const key in ["integrity", "crossorigin"]) if (script[key]) warn(`script with type="${TYPE_ATTRIBUTE_VALUE}" does not support ${key} attribute.`);
676
+ for (const key of ["integrity", "crossorigin"]) if (script[key]) warn(`script with type="${TYPE_ATTRIBUTE_VALUE}" does not support ${key} attribute.`);
658
677
  if (script.async) importScript(script);
659
678
  else await importScript(script);
660
679
  }
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- //#region src/importmap.d.ts
1
+ //#region src/import-map.d.ts
2
2
  type ModuleSpecifierMap = Map<string, URL | null>;
3
3
  interface SpecifierResolutionRecord {
4
4
  serializedBaseURL: string;
@@ -78,6 +78,10 @@ declare class ModuleTSX extends EventTarget implements IModuleTSX {
78
78
  /** Add a new import map, merging it into the existing one per the spec.
79
79
  * Rules that conflict with already-resolved modules are silently dropped. */
80
80
  addImportMap(newImportMap: ImportMap): void;
81
+ /** Resolve a blob URL back to its original source URL. Returns undefined if not found. */
82
+ getSourceUrlByBlob(blobUrl: string): string | undefined;
83
+ /** Get the original source code that was compiled into a given blob URL. */
84
+ getOriginalSource(blobUrl: string): string | undefined;
81
85
  private emit;
82
86
  import(id: string, options?: any): Promise<any>;
83
87
  importCode(sourceUrl: string, code: string, options?: any): Promise<any>;