@vorplex/compiler 0.0.15 → 0.0.21

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/dist/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  export * from './compiler.util';
2
- export * from './script-analyzer.util';
3
2
  export * from './module-loader/bundler';
4
3
  export * from './module-loader/module-loader.util';
4
+ export * from './npm/jsdelivr/jsdelivr.util';
5
5
  export * from './npm/npm.util';
6
6
  export * from './npm/package-json.type';
7
- export * from './npm/jsdelivr/jsdelivr.util';
7
+ export * from './script-analyzer.util';
package/dist/index.js CHANGED
@@ -1,8 +1,8 @@
1
1
  // **/*.ts
2
2
  export * from './compiler.util';
3
- export * from './script-analyzer.util';
4
3
  export * from './module-loader/bundler';
5
4
  export * from './module-loader/module-loader.util';
5
+ export * from './npm/jsdelivr/jsdelivr.util';
6
6
  export * from './npm/npm.util';
7
7
  export * from './npm/package-json.type';
8
- export * from './npm/jsdelivr/jsdelivr.util';
8
+ export * from './script-analyzer.util';
@@ -38,7 +38,7 @@ export class Bundler {
38
38
  const relative = args.path.startsWith('.') || args.path.startsWith('/');
39
39
  const importerPath = args.importer === '<stdin>' ? options.path : args.importer;
40
40
  const importPath = relative ? $Path.join(importerPath, `../${args.path}`) : args.path;
41
- importParent[importPath] = importerPath;
41
+ importParent[importPath] ??= importerPath;
42
42
  let importStack = [];
43
43
  let parentPath = importerPath;
44
44
  while (parentPath) {
@@ -1,3 +1,4 @@
1
+ import { type StorageProvider } from '@vorplex/core';
1
2
  import type { PackageJson } from '../package-json.type';
2
3
  export interface JsDelivrData {
3
4
  name: string;
@@ -10,23 +11,33 @@ export interface JsDelivrFileEntry {
10
11
  name: string;
11
12
  files: JsDelivrFileEntry[];
12
13
  }
14
+ export interface PackageFile {
15
+ packageName: string;
16
+ packageVersion: string;
17
+ url: string;
18
+ path?: string;
19
+ content: string;
20
+ }
21
+ export declare const JsDelivrCacheStore: {
22
+ readonly PackageVersion: "package-version";
23
+ readonly Data: "data";
24
+ readonly PackageJson: "package-json";
25
+ readonly FilePath: "file-path";
26
+ readonly File: "file";
27
+ readonly ImportFilePath: "import-filePath";
28
+ };
29
+ export type JsDelivrCacheStore = typeof JsDelivrCacheStore[keyof typeof JsDelivrCacheStore];
13
30
  export declare class JsDelivr {
14
31
  static readonly url: "https://cdn.jsdelivr.net/npm";
15
32
  static readonly dataUrl: "https://data.jsdelivr.com/v1/packages/npm";
16
33
  static readonly resolveUrl: "https://data.jsdelivr.com/v1/package/resolve/npm";
17
- static packageVersionCache: Record<string, Record<string, string>>;
34
+ static cache: StorageProvider<'js-delivr', JsDelivrCacheStore>;
18
35
  static resolveVersion(name: string, semanticVersion?: string): Promise<string>;
19
36
  static getPackageVersions(name: string): Promise<string[]>;
20
37
  static getData(name: string, semanticVersion: string): Promise<JsDelivrData>;
21
38
  static getFilePaths(name: string, semanticVersion: string, regex?: RegExp): Promise<string[]>;
22
39
  static resolveFilePath(name: string, semanticVersion: string, path: string): Promise<string>;
23
- static getFile(name: string, semanticVersion: string, path?: string): Promise<{
24
- packageName: string;
25
- packageVersion: string;
26
- url: string;
27
- path?: string;
28
- content: string;
29
- }>;
40
+ static getFile(name: string, semanticVersion: string, path?: string): Promise<PackageFile>;
30
41
  static getPackageJson(name: string, semanticVersion: string): Promise<PackageJson>;
31
42
  static parseUrl(url: string): {
32
43
  name: string;
@@ -1,19 +1,29 @@
1
- import { $Path, $String } from '@vorplex/core';
1
+ import { $Path, $String, InMemoryStorage } from '@vorplex/core';
2
+ export const JsDelivrCacheStore = {
3
+ PackageVersion: 'package-version',
4
+ Data: 'data',
5
+ PackageJson: 'package-json',
6
+ FilePath: 'file-path',
7
+ File: 'file',
8
+ ImportFilePath: 'import-filePath'
9
+ };
2
10
  export class JsDelivr {
3
11
  static url = 'https://cdn.jsdelivr.net/npm';
4
12
  static dataUrl = 'https://data.jsdelivr.com/v1/packages/npm';
5
13
  static resolveUrl = 'https://data.jsdelivr.com/v1/package/resolve/npm';
6
- static packageVersionCache = {};
14
+ static cache = new InMemoryStorage();
7
15
  static async resolveVersion(name, semanticVersion) {
8
16
  semanticVersion ??= 'latest';
9
- if (this.packageVersionCache[name]?.[semanticVersion])
10
- return this.packageVersionCache[name][semanticVersion];
17
+ const key = `${name}@${semanticVersion}`;
18
+ const cached = await this.cache.get('js-delivr', JsDelivrCacheStore.PackageVersion, key);
19
+ if (cached)
20
+ return cached;
11
21
  const url = $Path.join(this.resolveUrl, `${name}@${semanticVersion}`);
12
22
  const response = await fetch(url);
13
23
  if (!response.ok)
14
24
  throw new Error(`Failed to fetch package (${name}) version (${semanticVersion}). ${response.statusText}`);
15
25
  const data = (await response.json());
16
- this.packageVersionCache[name] = Object.assign({}, this.packageVersionCache[name], { [semanticVersion]: data.version });
26
+ await this.cache.set('js-delivr', JsDelivrCacheStore.PackageVersion, key, data.version);
17
27
  return data.version;
18
28
  }
19
29
  static async getPackageVersions(name) {
@@ -26,11 +36,17 @@ export class JsDelivr {
26
36
  }
27
37
  static async getData(name, semanticVersion) {
28
38
  const version = await this.resolveVersion(name, semanticVersion);
39
+ const key = `${name}@${version}`;
40
+ const cached = await this.cache.get('js-delivr', JsDelivrCacheStore.Data, key);
41
+ if (cached)
42
+ return cached;
29
43
  const url = $Path.join(this.dataUrl, `${name}@${version}`);
30
44
  const response = await fetch(url);
31
45
  if (!response.ok)
32
46
  throw new Error(`Failed to fetch package (${name}) metadata. ${response.statusText}`);
33
- return await response.json();
47
+ const data = await response.json();
48
+ await this.cache.set('js-delivr', JsDelivrCacheStore.Data, key, data);
49
+ return data;
34
50
  }
35
51
  static async getFilePaths(name, semanticVersion, regex) {
36
52
  const version = await this.resolveVersion(name, semanticVersion);
@@ -40,7 +56,8 @@ export class JsDelivr {
40
56
  for (const entry of target.files) {
41
57
  const entryPath = $Path.join(path, entry.name);
42
58
  if (entry.type === 'directory')
43
- files.push(...getFiles(entry, entryPath));
59
+ for (const file of getFiles(entry, entryPath))
60
+ files.push(file);
44
61
  else if (entryPath.match(regex))
45
62
  files.push(entryPath);
46
63
  }
@@ -49,7 +66,12 @@ export class JsDelivr {
49
66
  return getFiles(metadata, '/');
50
67
  }
51
68
  static async resolveFilePath(name, semanticVersion, path) {
52
- const paths = await this.getFilePaths(name, semanticVersion, new RegExp('^' + $String.sanitizeForRegex($Path.absolute(path)) + '(?:\\.js|/index.js)?$'));
69
+ const version = await this.resolveVersion(name, semanticVersion);
70
+ const key = `${name}@${version}:${path}`;
71
+ const cached = await this.cache.get('js-delivr', JsDelivrCacheStore.FilePath, key);
72
+ if (cached)
73
+ return cached;
74
+ const paths = await this.getFilePaths(name, version, new RegExp('^' + $String.sanitizeForRegex($Path.absolute(path)) + '(?:\\.js|/index.js)?$'));
53
75
  function getPathPriority(filePath) {
54
76
  if (filePath === path)
55
77
  return 4;
@@ -59,34 +81,56 @@ export class JsDelivr {
59
81
  return 2;
60
82
  return 1;
61
83
  }
62
- return paths.sort((a, b) => getPathPriority(b) - getPathPriority(a))[0];
84
+ const resolved = paths.sort((a, b) => getPathPriority(b) - getPathPriority(a))[0];
85
+ if (resolved)
86
+ await this.cache.set('js-delivr', JsDelivrCacheStore.FilePath, key, resolved);
87
+ return resolved;
63
88
  }
64
89
  static async getFile(name, semanticVersion, path) {
65
- const resolvedPath = path ? await this.resolveFilePath(name, semanticVersion, path) : null;
90
+ const resolvedVersion = await this.resolveVersion(name, semanticVersion);
91
+ const resolvedPath = path ? await this.resolveFilePath(name, resolvedVersion, path) : null;
66
92
  if (path && !resolvedPath)
67
93
  throw new Error(`Failed to resolve path (${path}) from package (${name}) version (${semanticVersion}). Not Found.`);
68
- const url = $Path.join(this.url, `${name}@${semanticVersion ?? 'latest'}`, resolvedPath);
94
+ const key = `${name}@${resolvedVersion}:${resolvedPath ?? ''}`;
95
+ const cached = await this.cache.get('js-delivr', JsDelivrCacheStore.File, key);
96
+ if (cached)
97
+ return cached;
98
+ const url = $Path.join(this.url, `${name}@${resolvedVersion}`, resolvedPath);
69
99
  const response = await fetch(url);
70
100
  if (!response.ok)
71
101
  throw new Error(`Failed to fetch package (${name}) file (${resolvedPath ?? '<default>'}). ${response.statusText}`);
72
102
  const version = response.headers.get('x-jsd-version');
73
- return {
103
+ const file = {
74
104
  packageName: name,
75
105
  packageVersion: version,
76
106
  url: $Path.join(this.url, `${name}@${version}`, resolvedPath),
77
107
  path: resolvedPath,
78
108
  content: await response.text(),
79
109
  };
110
+ await this.cache.set('js-delivr', JsDelivrCacheStore.File, key, file);
111
+ return file;
80
112
  }
81
113
  static async getPackageJson(name, semanticVersion) {
114
+ const version = await this.resolveVersion(name, semanticVersion);
115
+ const key = `${name}@${version}`;
116
+ const cached = await this.cache.get('js-delivr', JsDelivrCacheStore.PackageJson, key);
117
+ if (cached)
118
+ return cached;
82
119
  const { content } = await this.getFile(name, semanticVersion, 'package.json');
83
- return JSON.parse(content);
120
+ const packageJson = JSON.parse(content);
121
+ await this.cache.set('js-delivr', JsDelivrCacheStore.PackageJson, key, packageJson);
122
+ return packageJson;
84
123
  }
85
124
  static parseUrl(url) {
86
125
  return url.match(/https:\/\/cdn\.jsdelivr\.net\/npm\/(?<name>@?[^@]+)@(?<version>[^/]+)(?:\/(?<path>.*))?/)?.groups;
87
126
  }
88
127
  static async resolveImportFilePath(packageName, semanticVersion, subpath) {
89
- const packageJson = await this.getPackageJson(packageName, semanticVersion);
128
+ const version = await this.resolveVersion(packageName, semanticVersion);
129
+ const key = `${packageName}@${version}:${subpath ?? ''}`;
130
+ const cached = await this.cache.get('js-delivr', JsDelivrCacheStore.ImportFilePath, key);
131
+ if (cached)
132
+ return cached;
133
+ const packageJson = await this.getPackageJson(packageName, version);
90
134
  if (packageJson.exports) {
91
135
  const resolveExports = async (exports) => {
92
136
  const result = {};
@@ -138,18 +182,28 @@ export class JsDelivr {
138
182
  return result;
139
183
  };
140
184
  const exports = await resolveExports(packageJson.exports);
141
- if (!subpath && exports['.'])
142
- return $Path.absolute(exports['.']);
143
- if (subpath && exports[$Path.relative(subpath)])
144
- return $Path.absolute(exports[$Path.relative(subpath)]);
185
+ if (!subpath && exports['.']) {
186
+ const result = $Path.absolute(exports['.']);
187
+ await this.cache.set('js-delivr', JsDelivrCacheStore.ImportFilePath, key, result);
188
+ return result;
189
+ }
190
+ if (subpath && exports[$Path.relative(subpath)]) {
191
+ const result = $Path.absolute(exports[$Path.relative(subpath)]);
192
+ await this.cache.set('js-delivr', JsDelivrCacheStore.ImportFilePath, key, result);
193
+ return result;
194
+ }
145
195
  }
146
196
  if (subpath) {
147
- const file = await this.resolveFilePath(packageName, semanticVersion, subpath);
148
- if (file)
197
+ const file = await this.resolveFilePath(packageName, version, subpath);
198
+ if (file) {
199
+ await this.cache.set('js-delivr', JsDelivrCacheStore.ImportFilePath, key, file);
149
200
  return file;
201
+ }
150
202
  }
151
203
  else {
152
- return $Path.absolute(packageJson.module || packageJson.main || 'index.js');
204
+ const result = $Path.absolute(packageJson.module || packageJson.main || 'index.js');
205
+ await this.cache.set('js-delivr', JsDelivrCacheStore.ImportFilePath, key, result);
206
+ return result;
153
207
  }
154
208
  throw new Error(`Failed to resolve file path for import (${packageName}${subpath ? `/${subpath}` : ''}@${semanticVersion})`);
155
209
  }
@@ -50,31 +50,25 @@ export class NPM {
50
50
  seen[key] = node;
51
51
  if (pkg.dependencies) {
52
52
  task.log('Resolving packages dependencies.');
53
- for (const [depName, depRange] of Object.entries(pkg.dependencies)) {
54
- await task.do(`${depName}@${depRange}`, async (task) => {
55
- node.dependencies[depName] = await resolvePackage(depName, depRange, [node, ...ancestors], task);
56
- });
57
- }
53
+ await Promise.all(Object.entries(pkg.dependencies).map(async ([depName, depRange]) => await task.do(`${depName}@${depRange}`, async (task) => {
54
+ node.dependencies[depName] = await resolvePackage(depName, depRange, [node, ...ancestors], task);
55
+ })));
58
56
  task.log('Done resolving packages dependencies.');
59
57
  }
60
58
  if (pkg.peerDependencies) {
61
59
  task.log('Resolving packages peer-dependencies.');
62
- for (const [peerName, peerRange] of Object.entries(pkg.peerDependencies)) {
63
- await task.do(`${peerName}@${peerRange}`, async (task) => {
64
- node.dependencies[peerName] = await resolvePackage(peerName, peerRange, ancestors, task);
65
- });
66
- }
60
+ await Promise.all(Object.entries(pkg.peerDependencies).map(async ([peerName, peerRange]) => await task.do(`${peerName}@${peerRange}`, async (task) => {
61
+ node.dependencies[peerName] = await resolvePackage(peerName, peerRange, ancestors, task);
62
+ })));
67
63
  task.log('Done resolving packages peer-dependencies.');
68
64
  }
69
65
  return node;
70
66
  }
71
67
  const tree = {};
72
68
  task.log('Resolving packages');
73
- for (const [name, range] of Object.entries(packages)) {
74
- await task.do(`${name}@${range}`, async (task) => {
75
- tree[name] = await resolvePackage(name, range, [], task);
76
- });
77
- }
69
+ await Promise.all(Object.entries(packages).map(async ([name, range]) => await task.do(`${name}@${range}`, async (task) => {
70
+ tree[name] = await resolvePackage(name, range, [], task);
71
+ })));
78
72
  task.log('Done resolving packages');
79
73
  task.log('Done resolving dependency tree');
80
74
  return tree;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vorplex/compiler",
3
- "version": "0.0.15",
3
+ "version": "0.0.21",
4
4
  "type": "module",
5
5
  "sideEffects": false,
6
6
  "files": [
@@ -15,21 +15,19 @@
15
15
  "types": "./dist/index.d.ts",
16
16
  "main": "./dist/index.js",
17
17
  "dependencies": {
18
- "@vorplex/core": "0.0.15",
19
- "esbuild-wasm": "0.25.12",
18
+ "@vorplex/core": "0.0.21",
20
19
  "semver": "7.7.3",
21
20
  "tslib": "2.8.1",
21
+ "esbuild-wasm": "0.25.12",
22
22
  "typescript": "5.9.3",
23
23
  "yaml": "2.8.2"
24
24
  },
25
25
  "devDependencies": {
26
26
  "@types/semver": "7.7.1",
27
- "@types/jest": "29.5.14",
28
- "jest": "29.7.0",
29
- "ts-jest": "29.4.5"
27
+ "vitest": "3.2.4"
30
28
  },
31
29
  "scripts": {
32
30
  "build": "tsc -b --force tsconfig.build.json",
33
- "test": "jest"
31
+ "test": "vitest run"
34
32
  }
35
33
  }