@utoo/web 1.3.1 → 1.3.2

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.
@@ -7,6 +7,34 @@ const statCache = {};
7
7
  const pkgJsonCache = {};
8
8
  const resolutionCache = {};
9
9
  const searchPathsCache = {};
10
+ const RESOLUTION_EXTENSIONS = [
11
+ "",
12
+ ".js",
13
+ ".cjs",
14
+ ".json",
15
+ "/index.js",
16
+ "/index.cjs",
17
+ "/index.json",
18
+ ];
19
+ const tryReadFile = (p) => {
20
+ try {
21
+ return fs.readFileSync(p, "utf8");
22
+ }
23
+ catch (_a) {
24
+ return null;
25
+ }
26
+ };
27
+ const resolveWithExtensions = (p, skipIndexJsIfJs = false) => {
28
+ for (const ext of RESOLUTION_EXTENSIONS) {
29
+ if (skipIndexJsIfJs && ext === "/index.js" && p.endsWith(".js"))
30
+ continue;
31
+ const candidate = p + ext;
32
+ const code = tryReadFile(candidate);
33
+ if (code !== null)
34
+ return { code, id: candidate };
35
+ }
36
+ return null;
37
+ };
10
38
  const executeModule = (moduleCode, moduleId, id, importMaps, entrypoint) => {
11
39
  if (installedModules[moduleId]) {
12
40
  return installedModules[moduleId].exports;
@@ -19,7 +47,6 @@ const executeModule = (moduleCode, moduleId, id, importMaps, entrypoint) => {
19
47
  if (moduleId.includes("node_modules")) {
20
48
  installedModules[moduleId] = module;
21
49
  }
22
- // Hack for entrypoint
23
50
  if (moduleId === entrypoint) {
24
51
  moduleCode = "self.Buffer = require('buffer').Buffer;" + moduleCode;
25
52
  }
@@ -44,15 +71,14 @@ const executeModule = (moduleCode, moduleId, id, importMaps, entrypoint) => {
44
71
  console.warn = (...args) => {
45
72
  var _a;
46
73
  const msg = ((_a = args[0]) === null || _a === void 0 ? void 0 : _a.toString()) || "";
47
- if (msg.includes("(SystemJS Error#W3")) {
48
- return;
74
+ if (!msg.includes("(SystemJS Error#W3")) {
75
+ originalWarn.apply(console, args);
49
76
  }
50
- originalWarn.apply(console, args);
51
77
  };
52
78
  try {
53
79
  System.set(moduleId, { default: finalExports });
54
80
  }
55
- catch (e) {
81
+ catch (_a) {
56
82
  // ignore
57
83
  }
58
84
  finally {
@@ -61,47 +87,52 @@ const executeModule = (moduleCode, moduleId, id, importMaps, entrypoint) => {
61
87
  return finalExports;
62
88
  };
63
89
  const loadModule = (id, context, importMaps, entrypoint) => {
90
+ var _a;
64
91
  const cacheKey = `${context}:${id}`;
65
92
  if (resolutionCache[cacheKey]) {
66
93
  const cachedId = resolutionCache[cacheKey];
67
- if (installedModules[cachedId]) {
94
+ if (installedModules[cachedId])
68
95
  return installedModules[cachedId].exports;
69
- }
70
- // Fast path: if we know the resolved path, try to load it directly
71
- try {
72
- const moduleCode = fs.readFileSync(cachedId, "utf8");
73
- return executeModule(moduleCode, cachedId, id, importMaps, entrypoint);
74
- }
75
- catch (e) {
76
- // If read fails, fall back to full resolution
96
+ const code = tryReadFile(cachedId);
97
+ if (code !== null) {
98
+ return executeModule(code, cachedId, id, importMaps, entrypoint);
77
99
  }
78
100
  }
79
101
  // 1. Resolve
80
- let resolvedId = id;
81
- if (id.startsWith(".")) {
82
- resolvedId = path.join(context, id);
83
- }
102
+ let resolvedId = id.startsWith(".") ? path.join(context, id) : id;
84
103
  // 2. Check Cache (SystemJS)
85
- let dependency = System.get(resolvedId);
86
- if (dependency)
87
- return dependency.default;
88
- if (id !== resolvedId) {
89
- dependency = System.get(id);
90
- if (dependency)
91
- return dependency.default;
92
- }
104
+ const sysDef = System.get(resolvedId) || (id !== resolvedId && System.get(id));
105
+ if (sysDef)
106
+ return sysDef.default;
93
107
  // 3. Check Node Polyfills
94
- if (id in nodePolyFills) {
95
- // @ts-ignore
108
+ if (id in nodePolyFills)
96
109
  return nodePolyFills[id];
97
- }
98
- if (resolvedId in nodePolyFills) {
99
- // @ts-ignore
110
+ if (resolvedId in nodePolyFills)
100
111
  return nodePolyFills[resolvedId];
101
- }
102
112
  // 4. Check importMaps & FS
103
113
  let moduleCode = importMaps[resolvedId] || importMaps[id];
104
114
  let moduleId = importMaps[resolvedId] ? resolvedId : id;
115
+ if (!moduleCode) {
116
+ let longestMatch = null;
117
+ for (const key in importMaps) {
118
+ const sanitized = key.replace(/^\.?\//, "");
119
+ if (!sanitized)
120
+ continue;
121
+ const isMatch = [id, resolvedId].some((p) => p.startsWith("/") &&
122
+ p.endsWith(sanitized) &&
123
+ p[p.length - sanitized.length - 1] === "/");
124
+ if (isMatch && (!longestMatch || key.length > longestMatch.key.length)) {
125
+ longestMatch = { key, sanitized };
126
+ }
127
+ }
128
+ if (longestMatch) {
129
+ moduleCode = importMaps[longestMatch.key];
130
+ moduleId =
131
+ id.startsWith("/") && id.endsWith(longestMatch.sanitized)
132
+ ? id
133
+ : resolvedId;
134
+ }
135
+ }
105
136
  // Fallback: Try resolving from node_modules
106
137
  if (!moduleCode && !id.startsWith(".") && !id.startsWith("/")) {
107
138
  let searchPaths = searchPathsCache[context];
@@ -110,140 +141,76 @@ const loadModule = (id, context, importMaps, entrypoint) => {
110
141
  let currentDir = context;
111
142
  while (true) {
112
143
  if (path.basename(currentDir) !== "node_modules") {
113
- const nodeModulesPath = path.join(currentDir, "node_modules");
114
- if (!searchPaths.includes(nodeModulesPath)) {
115
- searchPaths.push(nodeModulesPath);
116
- }
144
+ const nmPath = path.join(currentDir, "node_modules");
145
+ if (!searchPaths.includes(nmPath))
146
+ searchPaths.push(nmPath);
117
147
  }
118
148
  const parent = path.dirname(currentDir);
119
149
  if (parent === currentDir)
120
150
  break;
121
151
  currentDir = parent;
122
152
  }
123
- // Ensure cwd/node_modules is always included
124
- const cwd = nodePolyFills.process.cwd();
125
- const cwdNodeModules = path.join(cwd, "node_modules");
126
- if (!searchPaths.includes(cwdNodeModules)) {
127
- searchPaths.push(cwdNodeModules);
128
- }
153
+ const cwdNm = path.join(nodePolyFills.process.cwd(), "node_modules");
154
+ if (!searchPaths.includes(cwdNm))
155
+ searchPaths.push(cwdNm);
129
156
  searchPathsCache[context] = searchPaths;
130
157
  }
131
158
  for (const nodeModulesDir of searchPaths) {
132
159
  const nodeModulesPath = path.join(nodeModulesDir, id);
133
- // Check package.json first
134
- const pkgJsonPath = path.join(nodeModulesPath, "package.json");
135
- let pkg;
136
- try {
137
- const content = fs.readFileSync(pkgJsonPath, "utf8");
138
- pkg = JSON.parse(content);
139
- pkgJsonCache[pkgJsonPath] = pkg;
140
- }
141
- catch (e) {
142
- // ignore
143
- }
144
- if (pkg) {
145
- try {
146
- const mainField = pkg.main;
147
- if (mainField) {
148
- const candidates = [
149
- path.resolve(nodeModulesPath, mainField),
150
- path.resolve(nodeModulesPath, mainField) + ".js",
151
- path.resolve(nodeModulesPath, mainField) + ".json",
152
- path.resolve(nodeModulesPath, mainField, "index.js"),
153
- ];
154
- for (const candidate of candidates) {
155
- try {
156
- // Try reading directly to bypass potential statSync issues
157
- moduleCode = fs.readFileSync(candidate, "utf8");
158
- resolvedId = candidate;
159
- moduleId = candidate;
160
- break;
161
- }
162
- catch (e) {
163
- // ignore
164
- }
165
- }
160
+ const pkgPath = path.join(nodeModulesPath, "package.json");
161
+ // Check package.json main
162
+ let pkgMain;
163
+ if (!pkgJsonCache[pkgPath]) {
164
+ const json = tryReadFile(pkgPath);
165
+ if (json) {
166
+ try {
167
+ pkgJsonCache[pkgPath] = JSON.parse(json);
166
168
  }
167
- }
168
- catch (e) {
169
- // ignore
169
+ catch (_b) { }
170
170
  }
171
171
  }
172
- if (!moduleCode) {
173
- const extensions = ["", ".js", ".json", "/index.js"];
174
- for (const ext of extensions) {
175
- const p = nodeModulesPath + ext;
176
- try {
177
- // Try reading directly
178
- moduleCode = fs.readFileSync(p, "utf8");
179
- resolvedId = p;
180
- moduleId = p;
181
- break;
182
- }
183
- catch (e) {
184
- // ignore
185
- }
172
+ if ((_a = pkgJsonCache[pkgPath]) === null || _a === void 0 ? void 0 : _a.main) {
173
+ pkgMain = path.resolve(nodeModulesPath, pkgJsonCache[pkgPath].main);
174
+ const res = resolveWithExtensions(pkgMain);
175
+ if (res) {
176
+ moduleCode = res.code;
177
+ moduleId = resolvedId = res.id;
178
+ break;
186
179
  }
187
180
  }
188
- if (moduleCode)
189
- break;
190
- }
191
- }
192
- // Fallback: Try resolving absolute path
193
- if (!moduleCode && id.startsWith("/")) {
194
- const extensions = ["", ".js", ".json", "/index.js"];
195
- for (const ext of extensions) {
196
- if (ext === "/index.js" && id.endsWith(".js"))
197
- continue;
198
- const p = id + ext;
199
- try {
200
- moduleCode = fs.readFileSync(p, "utf8");
201
- resolvedId = p;
202
- moduleId = id;
181
+ // Check direct file/directory
182
+ const res = resolveWithExtensions(nodeModulesPath);
183
+ if (res) {
184
+ moduleCode = res.code;
185
+ moduleId = resolvedId = res.id;
203
186
  break;
204
187
  }
205
- catch (e) {
206
- // ignore
207
- }
208
188
  }
209
189
  }
210
- if (!moduleCode) {
211
- // Try extensions
212
- const extensions = ["", ".js", ".json", "/index.js"];
213
- for (const ext of extensions) {
214
- if (ext === "/index.js" && id.endsWith(".js"))
215
- continue;
216
- const p = resolvedId + ext;
217
- try {
218
- moduleCode = fs.readFileSync(p, "utf8");
219
- resolvedId = p;
220
- moduleId = p;
221
- break;
222
- }
223
- catch (e) {
224
- // ignore
225
- }
190
+ // Fallback: Try resolving absolute or relative path
191
+ if (!moduleCode && (id.startsWith("/") || id.startsWith("."))) {
192
+ const res = resolveWithExtensions(resolvedId, id.endsWith(".js"));
193
+ if (res) {
194
+ moduleCode = res.code;
195
+ moduleId = resolvedId = res.id;
226
196
  }
227
197
  }
228
198
  if (moduleCode) {
229
- const cacheKey = `${context}:${id}`;
230
- resolutionCache[cacheKey] = moduleId;
199
+ resolutionCache[`${context}:${id}`] = moduleId;
231
200
  return executeModule(moduleCode, moduleId, id, importMaps, entrypoint);
232
201
  }
233
- const error = new Error(`Worker: Dependency ${id} (resolved: ${resolvedId}) not found. Context: ${context}`);
202
+ const error = new Error(`Worker: Dependency ${id} (resolved: ${resolvedId}) not found. Context: ${context}. ` +
203
+ `ImportMaps count: ${Object.keys(importMaps).length}. ` +
204
+ `CWD: ${nodePolyFills.process.cwd()}. ` +
205
+ `Sample ImportMaps keys: ${Object.keys(importMaps).slice(0, 5).join(", ")}`);
234
206
  console.error(error);
235
207
  throw error;
236
208
  };
237
209
  export async function cjs(entrypoint, importMaps) {
238
- // Clear caches to avoid stale data across runs
239
- for (const key in statCache)
240
- delete statCache[key];
241
- for (const key in pkgJsonCache)
242
- delete pkgJsonCache[key];
243
- for (const key in resolutionCache)
244
- delete resolutionCache[key];
245
- for (const key in searchPathsCache)
246
- delete searchPathsCache[key];
210
+ [statCache, pkgJsonCache, resolutionCache, searchPathsCache].forEach((c) => {
211
+ for (const key in c)
212
+ delete c[key];
213
+ });
247
214
  await Promise.all(Object.entries(importMaps).map(async ([k, v]) => {
248
215
  if (v.startsWith("https://")) {
249
216
  try {
@@ -252,18 +219,17 @@ export async function cjs(entrypoint, importMaps) {
252
219
  importMaps[k] = await response.text();
253
220
  }
254
221
  else {
255
- console.error(`Failed to fetch loader '${k}' from ${v}: ${response.status} ${response.statusText}`);
222
+ console.error(`Failed to fetch loader '${k}': ${response.status}`);
256
223
  delete importMaps[k];
257
224
  }
258
225
  }
259
226
  catch (error) {
260
- console.error(`Error fetching loader '${k}' from ${v}:`, error);
227
+ console.error(`Error fetching loader '${k}':`, error);
261
228
  delete importMaps[k];
262
229
  }
263
230
  }
264
231
  }));
265
232
  // @ts-ignore
266
- // a hack for loader-runner resolving
267
233
  self.__systemjs_require__ = (id) => loadModule(id, path.dirname(entrypoint), importMaps, entrypoint);
268
234
  // @ts-ignore
269
235
  self.__systemjs_require__.resolve = (request) => request;
@@ -1,4 +1,5 @@
1
1
  import path from "path";
2
+ import { ERR_ABORT, ERR_INVALID_STATE, ERR_NO_MODIFICATION_ALLOWED, ERR_NOT_ALLOWED, ERR_NOT_FOUND, ERR_QUOTA_EXCEEDED, ERR_TYPE_MISMATCH, } from "../../../utoo";
2
3
  import { workerData } from "../workerThreadsPolyfill";
3
4
  export function resolvePath(p) {
4
5
  var _a, _b;
@@ -16,7 +17,9 @@ export function getFs() {
16
17
  }
17
18
  export function translateError(error, path, syscall) {
18
19
  const message = error.message || String(error);
19
- if (message.includes("NotFound")) {
20
+ // 1. NotFound (ENOENT)
21
+ // Mapping "NotFoundError" from tokio-fs-ext
22
+ if (message.includes(ERR_NOT_FOUND())) {
20
23
  const e = new Error(`ENOENT: no such file or directory, ${syscall} '${path}'`);
21
24
  e.errno = -2;
22
25
  e.code = "ENOENT";
@@ -24,5 +27,65 @@ export function translateError(error, path, syscall) {
24
27
  e.path = path;
25
28
  return e;
26
29
  }
30
+ // 2. Directory error (Mapped to EISDIR)
31
+ // Mapping "TypeMismatchError" or "type mismatch" from tokio-fs-ext
32
+ if (message.includes(ERR_TYPE_MISMATCH())) {
33
+ const e = new Error(`EISDIR: illegal operation on a directory, ${syscall} '${path}'`);
34
+ e.errno = -21;
35
+ e.code = "EISDIR";
36
+ e.syscall = syscall;
37
+ e.path = path;
38
+ return e;
39
+ }
40
+ // 3. Locking/Concurrency (Mapped to EAGAIN/EBUSY)
41
+ // Mapping "NoModificationAllowedError" from tokio-fs-ext
42
+ if (message.includes(ERR_NO_MODIFICATION_ALLOWED())) {
43
+ const e = new Error(`EAGAIN: resource temporarily unavailable, ${syscall} '${path}'`);
44
+ e.errno = -11;
45
+ e.code = "EAGAIN";
46
+ e.syscall = syscall;
47
+ e.path = path;
48
+ return e;
49
+ }
50
+ // 4. Permission Denied (EACCES)
51
+ // Mapping "NotAllowedError" from tokio-fs-ext
52
+ if (message.includes(ERR_NOT_ALLOWED())) {
53
+ const e = new Error(`EACCES: permission denied, ${syscall} '${path}'`);
54
+ e.errno = -13;
55
+ e.code = "EACCES";
56
+ e.syscall = syscall;
57
+ e.path = path;
58
+ return e;
59
+ }
60
+ // 5. Storage Full (ENOSPC)
61
+ // Mapping "QuotaExceededError" from tokio-fs-ext
62
+ if (message.includes(ERR_QUOTA_EXCEEDED())) {
63
+ const e = new Error(`ENOSPC: no space left on device, ${syscall} '${path}'`);
64
+ e.errno = -28;
65
+ e.code = "ENOSPC";
66
+ e.syscall = syscall;
67
+ e.path = path;
68
+ return e;
69
+ }
70
+ // 6. Invalid Argument (EINVAL)
71
+ // Mapping "InvalidStateError" from tokio-fs-ext
72
+ if (message.includes(ERR_INVALID_STATE())) {
73
+ const e = new Error(`EINVAL: invalid argument, ${syscall} '${path}'`);
74
+ e.errno = -22;
75
+ e.code = "EINVAL";
76
+ e.syscall = syscall;
77
+ e.path = path;
78
+ return e;
79
+ }
80
+ // 7. Interrupted (EINTR)
81
+ // Mapping "AbortError" from tokio-fs-ext
82
+ if (message.includes(ERR_ABORT())) {
83
+ const e = new Error(`EINTR: interrupted system call, ${syscall} '${path}'`);
84
+ e.errno = -4;
85
+ e.code = "EINTR";
86
+ e.syscall = syscall;
87
+ e.path = path;
88
+ return e;
89
+ }
27
90
  return error;
28
91
  }
@@ -1,4 +1,4 @@
1
- import * as fs from "./fsPolyfill/sync";
1
+ import * as fs from "./fsPolyfill";
2
2
  declare const _default: {
3
3
  readonly assert: any;
4
4
  readonly "node:assert": any;
@@ -1,4 +1,4 @@
1
- import * as fs from "./fsPolyfill/sync";
1
+ import * as fs from "./fsPolyfill";
2
2
  import * as workerThreads from "./workerThreadsPolyfill";
3
3
  const buffer = require("buffer");
4
4
  self.Buffer = buffer.Buffer;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@utoo/web",
3
- "version": "1.3.1",
3
+ "version": "1.3.2",
4
4
  "module": "esm/index.js",
5
5
  "types": "esm/index.d.ts",
6
6
  "files": [