@hakobu/hakobu 1.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 (284) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +673 -0
  3. package/dictionary/angular-bridge.js +3 -0
  4. package/dictionary/any-promise.js +3 -0
  5. package/dictionary/async.js +3 -0
  6. package/dictionary/aws-sdk.js +7 -0
  7. package/dictionary/babel-core.js +3 -0
  8. package/dictionary/batch.js +3 -0
  9. package/dictionary/bcrypt.js +3 -0
  10. package/dictionary/better-sqlite3.js +3 -0
  11. package/dictionary/bignum.js +3 -0
  12. package/dictionary/bindings.js +3 -0
  13. package/dictionary/blessed.js +8 -0
  14. package/dictionary/body-parser.js +9 -0
  15. package/dictionary/browserify.js +7 -0
  16. package/dictionary/bson.js +3 -0
  17. package/dictionary/buffermaker.js +7 -0
  18. package/dictionary/bunyan.js +9 -0
  19. package/dictionary/busboy.js +7 -0
  20. package/dictionary/bytes.js +3 -0
  21. package/dictionary/callsites.js +3 -0
  22. package/dictionary/chokidar.js +3 -0
  23. package/dictionary/coffee-script.js +7 -0
  24. package/dictionary/colors.js +3 -0
  25. package/dictionary/compression.js +3 -0
  26. package/dictionary/compressjs.js +7 -0
  27. package/dictionary/connect-mongo.js +3 -0
  28. package/dictionary/connect-mongodb.js +3 -0
  29. package/dictionary/connect-redis.js +3 -0
  30. package/dictionary/connect.js +10 -0
  31. package/dictionary/consolidate.js +3 -0
  32. package/dictionary/cookie-parser.js +3 -0
  33. package/dictionary/cookie.js +3 -0
  34. package/dictionary/cors.js +3 -0
  35. package/dictionary/cron.js +3 -0
  36. package/dictionary/cross-env.js +11 -0
  37. package/dictionary/cross-spawn-async.js +3 -0
  38. package/dictionary/curve25519.js +3 -0
  39. package/dictionary/data-preflight.js +7 -0
  40. package/dictionary/debug.js +3 -0
  41. package/dictionary/denymount.js +3 -0
  42. package/dictionary/diff.js +3 -0
  43. package/dictionary/drivelist.js +22 -0
  44. package/dictionary/ed25519.js +3 -0
  45. package/dictionary/ejs.js +3 -0
  46. package/dictionary/elasticsearch.js +3 -0
  47. package/dictionary/electron.js +17 -0
  48. package/dictionary/emailjs.js +3 -0
  49. package/dictionary/engine.io.js +3 -0
  50. package/dictionary/epoll.js +3 -0
  51. package/dictionary/errorhandler.js +7 -0
  52. package/dictionary/errors.js +7 -0
  53. package/dictionary/eslint.js +7 -0
  54. package/dictionary/etcher-image-write.js +3 -0
  55. package/dictionary/exceljs.js +21 -0
  56. package/dictionary/exiftool.exe.js +13 -0
  57. package/dictionary/exiftool.pl.js +13 -0
  58. package/dictionary/express-load.js +12 -0
  59. package/dictionary/express-session.js +3 -0
  60. package/dictionary/express.js +14 -0
  61. package/dictionary/extender.js +11 -0
  62. package/dictionary/extsprintf.js +3 -0
  63. package/dictionary/faye-websocket.js +3 -0
  64. package/dictionary/feathers.js +3 -0
  65. package/dictionary/findup-sync.js +3 -0
  66. package/dictionary/floordate.js +3 -0
  67. package/dictionary/fmt.js +3 -0
  68. package/dictionary/formidable.js +3 -0
  69. package/dictionary/fs-extra.js +3 -0
  70. package/dictionary/fsevents.js +3 -0
  71. package/dictionary/geoip-lite.js +7 -0
  72. package/dictionary/github.js +7 -0
  73. package/dictionary/gm.js +3 -0
  74. package/dictionary/google-closure-compiler-java.js +13 -0
  75. package/dictionary/google-closure-compiler.js +13 -0
  76. package/dictionary/googleapis.js +7 -0
  77. package/dictionary/got.js +3 -0
  78. package/dictionary/graceful-fs.js +19 -0
  79. package/dictionary/grpc.js +11 -0
  80. package/dictionary/gulp.js +3 -0
  81. package/dictionary/hap-nodejs.js +3 -0
  82. package/dictionary/heapdump.js +3 -0
  83. package/dictionary/hoek.js +3 -0
  84. package/dictionary/homebridge.js +3 -0
  85. package/dictionary/http-proxy.js +3 -0
  86. package/dictionary/http-server.js +3 -0
  87. package/dictionary/image-size.js +3 -0
  88. package/dictionary/indexof.js +3 -0
  89. package/dictionary/inquirer.js +3 -0
  90. package/dictionary/j.js +16 -0
  91. package/dictionary/jade.js +3 -0
  92. package/dictionary/jsdom.js +3 -0
  93. package/dictionary/json-stringify-date.js +3 -0
  94. package/dictionary/json-stringify-safe.js +3 -0
  95. package/dictionary/jsonwebtoken.js +3 -0
  96. package/dictionary/kerberos.js +3 -0
  97. package/dictionary/knex.js +7 -0
  98. package/dictionary/later.js +7 -0
  99. package/dictionary/level.js +3 -0
  100. package/dictionary/leveldown.js +10 -0
  101. package/dictionary/levelup.js +3 -0
  102. package/dictionary/liftoff.js +12 -0
  103. package/dictionary/lodash.js +3 -0
  104. package/dictionary/log4js.js +7 -0
  105. package/dictionary/logform.js +7 -0
  106. package/dictionary/machinepack-urls.js +7 -0
  107. package/dictionary/markdown.js +3 -0
  108. package/dictionary/mdns.js +6 -0
  109. package/dictionary/method-override.js +3 -0
  110. package/dictionary/microjob.js +16 -0
  111. package/dictionary/mime-types.js +3 -0
  112. package/dictionary/mime.js +3 -0
  113. package/dictionary/minimatch.js +3 -0
  114. package/dictionary/minstache.js +3 -0
  115. package/dictionary/module-deps.js +3 -0
  116. package/dictionary/moment-timezone.js +3 -0
  117. package/dictionary/moment.js +7 -0
  118. package/dictionary/mongodb-core.js +22 -0
  119. package/dictionary/mongodb.js +7 -0
  120. package/dictionary/mongoose.js +7 -0
  121. package/dictionary/mongoskin.js +7 -0
  122. package/dictionary/ms.js +3 -0
  123. package/dictionary/msgpack.js +3 -0
  124. package/dictionary/multer.js +3 -0
  125. package/dictionary/muri.js +3 -0
  126. package/dictionary/native-or-bluebird.js +3 -0
  127. package/dictionary/natives.js +3 -0
  128. package/dictionary/nconf.js +7 -0
  129. package/dictionary/nedb.js +3 -0
  130. package/dictionary/negotiator.js +7 -0
  131. package/dictionary/newrelic.js +3 -0
  132. package/dictionary/nib.js +3 -0
  133. package/dictionary/nightmare.js +18 -0
  134. package/dictionary/node-forge.js +7 -0
  135. package/dictionary/node-libcurl.js +3 -0
  136. package/dictionary/node-notifier.js +30 -0
  137. package/dictionary/node-pre-gyp.js +7 -0
  138. package/dictionary/node-redis-pubsub.js +3 -0
  139. package/dictionary/node-sass.js +3 -0
  140. package/dictionary/node-uuid.js +3 -0
  141. package/dictionary/node-xlsx.js +3 -0
  142. package/dictionary/node-zookeeper-client.js +7 -0
  143. package/dictionary/nodegit.js +7 -0
  144. package/dictionary/nodemailer-sendmail-transport.js +3 -0
  145. package/dictionary/nodemailer.js +3 -0
  146. package/dictionary/npm-registry-client.js +7 -0
  147. package/dictionary/npm.js +7 -0
  148. package/dictionary/nssocket.js +3 -0
  149. package/dictionary/oauth2orize.js +7 -0
  150. package/dictionary/octobat.js +3 -0
  151. package/dictionary/open.js +13 -0
  152. package/dictionary/opn.js +4 -0
  153. package/dictionary/optimist.js +3 -0
  154. package/dictionary/passport-local.js +3 -0
  155. package/dictionary/passport.js +3 -0
  156. package/dictionary/pg-cursor.js +3 -0
  157. package/dictionary/pg-query-stream.js +3 -0
  158. package/dictionary/pg-types.js +7 -0
  159. package/dictionary/pg.js +7 -0
  160. package/dictionary/pg.js.js +7 -0
  161. package/dictionary/pgpass.js +7 -0
  162. package/dictionary/phantom.js +19 -0
  163. package/dictionary/phantomjs-prebuilt.js +16 -0
  164. package/dictionary/pkginfo.js +3 -0
  165. package/dictionary/pm2.js +7 -0
  166. package/dictionary/pmx.js +3 -0
  167. package/dictionary/pouchdb.js +3 -0
  168. package/dictionary/primus-emitter.js +3 -0
  169. package/dictionary/primus-spark-latency.js +3 -0
  170. package/dictionary/primus.js +3 -0
  171. package/dictionary/publicsuffixlist.js +15 -0
  172. package/dictionary/pug.js +3 -0
  173. package/dictionary/punt.js +3 -0
  174. package/dictionary/puppeteer.js +13 -0
  175. package/dictionary/pwd.js +3 -0
  176. package/dictionary/q.js +3 -0
  177. package/dictionary/raven.js +3 -0
  178. package/dictionary/rc.js +12 -0
  179. package/dictionary/readable-stream.js +3 -0
  180. package/dictionary/rechoir.js +3 -0
  181. package/dictionary/redis-parser.js +3 -0
  182. package/dictionary/redis.js +3 -0
  183. package/dictionary/regression.js +3 -0
  184. package/dictionary/reload.js +7 -0
  185. package/dictionary/request.js +3 -0
  186. package/dictionary/require-uncached.js +3 -0
  187. package/dictionary/require_optional.js +3 -0
  188. package/dictionary/s3.js +3 -0
  189. package/dictionary/safe_datejs.js +3 -0
  190. package/dictionary/sails.js +33 -0
  191. package/dictionary/sax.js +3 -0
  192. package/dictionary/scrypt.js +3 -0
  193. package/dictionary/semver.js +3 -0
  194. package/dictionary/sequelize.js +7 -0
  195. package/dictionary/serialport.js +3 -0
  196. package/dictionary/sha3.js +3 -0
  197. package/dictionary/sharp.js +11 -0
  198. package/dictionary/shelljs.js +7 -0
  199. package/dictionary/sinon.js +3 -0
  200. package/dictionary/socket.io-client.js +13 -0
  201. package/dictionary/socket.io.js +12 -0
  202. package/dictionary/sqip.js +7 -0
  203. package/dictionary/sqlite3.js +7 -0
  204. package/dictionary/steam-crypto.js +7 -0
  205. package/dictionary/steam-resources.js +19 -0
  206. package/dictionary/steam.js +3 -0
  207. package/dictionary/stripe-webhook-middleware.js +3 -0
  208. package/dictionary/stripe.js +3 -0
  209. package/dictionary/strong-globalize.js +3 -0
  210. package/dictionary/stylus.js +14 -0
  211. package/dictionary/supervisor.js +3 -0
  212. package/dictionary/svgo.js +8 -0
  213. package/dictionary/tabtab.js +3 -0
  214. package/dictionary/tesseract.js.js +7 -0
  215. package/dictionary/thread-stream.js +7 -0
  216. package/dictionary/throng.js +3 -0
  217. package/dictionary/time.js +3 -0
  218. package/dictionary/tinify.js +7 -0
  219. package/dictionary/tiny-worker.js +7 -0
  220. package/dictionary/tmp.js +3 -0
  221. package/dictionary/transformers.js +3 -0
  222. package/dictionary/uglify-js.js +9 -0
  223. package/dictionary/umd.js +19 -0
  224. package/dictionary/underscore.js +3 -0
  225. package/dictionary/union.js +3 -0
  226. package/dictionary/update-notifier.js +3 -0
  227. package/dictionary/usage.js +7 -0
  228. package/dictionary/v8flags.js +13 -0
  229. package/dictionary/verror.js +3 -0
  230. package/dictionary/voc.js +3 -0
  231. package/dictionary/webdriverio.js +7 -0
  232. package/dictionary/winston-uber.js +7 -0
  233. package/dictionary/winston.js +7 -0
  234. package/dictionary/ws.js +3 -0
  235. package/dictionary/xlsx.js +16 -0
  236. package/dictionary/xml2js.js +3 -0
  237. package/dictionary/yargs.js +3 -0
  238. package/dictionary/zeromq.js +13 -0
  239. package/lib-es5/addon-extract.js +164 -0
  240. package/lib-es5/analyzer.js +687 -0
  241. package/lib-es5/app-bundle.js +133 -0
  242. package/lib-es5/appdir.js +265 -0
  243. package/lib-es5/bin.js +304 -0
  244. package/lib-es5/bootstrap.js +179 -0
  245. package/lib-es5/bundler.js +496 -0
  246. package/lib-es5/chmod.js +15 -0
  247. package/lib-es5/colors.js +12 -0
  248. package/lib-es5/commands.js +376 -0
  249. package/lib-es5/common.js +328 -0
  250. package/lib-es5/compress_type.js +10 -0
  251. package/lib-es5/config.js +291 -0
  252. package/lib-es5/detector.js +421 -0
  253. package/lib-es5/esm-hooks.js +366 -0
  254. package/lib-es5/esm-resolver.js +292 -0
  255. package/lib-es5/esm-transformer.js +378 -0
  256. package/lib-es5/exports-resolver.js +184 -0
  257. package/lib-es5/external-artifacts.js +170 -0
  258. package/lib-es5/fabricator.js +137 -0
  259. package/lib-es5/follow.js +190 -0
  260. package/lib-es5/help.js +52 -0
  261. package/lib-es5/index.d.ts +2 -0
  262. package/lib-es5/index.js +552 -0
  263. package/lib-es5/log.js +7 -0
  264. package/lib-es5/mach-o.js +262 -0
  265. package/lib-es5/manifest.js +21 -0
  266. package/lib-es5/options.js +19 -0
  267. package/lib-es5/packager.js +1036 -0
  268. package/lib-es5/packer.js +137 -0
  269. package/lib-es5/pe-metadata.js +130 -0
  270. package/lib-es5/producer.js +378 -0
  271. package/lib-es5/refiner.js +87 -0
  272. package/lib-es5/resolver.js +142 -0
  273. package/lib-es5/runtime-diagnostics.js +172 -0
  274. package/lib-es5/sea.js +307 -0
  275. package/lib-es5/snapshot-fs-patch.js +396 -0
  276. package/lib-es5/snapshot-fs.js +255 -0
  277. package/lib-es5/snapshot-index.js +135 -0
  278. package/lib-es5/snapshot-path.js +168 -0
  279. package/lib-es5/types.js +9 -0
  280. package/lib-es5/walker.js +1019 -0
  281. package/lib-es5/windows-sign.js +139 -0
  282. package/package.json +99 -0
  283. package/prelude/bootstrap.js +2263 -0
  284. package/prelude/diagnostic.js +147 -0
@@ -0,0 +1,366 @@
1
+ "use strict";
2
+ /**
3
+ * Hakobu ESM Loader Hooks — hook code generator
4
+ *
5
+ * Generates the self-contained JavaScript code that runs inside Node's
6
+ * loader thread via module.register(). The code is passed as a data: URL
7
+ * because the loader thread cannot import from the main thread's modules.
8
+ *
9
+ * The hook code receives snapshot data via initialize() and serves
10
+ * resolve/load for snapshot-owned modules.
11
+ */
12
+ Object.defineProperty(exports, "__esModule", { value: true });
13
+ exports.getHookSource = void 0;
14
+ /**
15
+ * Returns the self-contained ESM hook source code as a string.
16
+ * This code will be registered via module.register('data:text/javascript,...')
17
+ */
18
+ function getHookSource() {
19
+ return HOOK_SOURCE;
20
+ }
21
+ exports.getHookSource = getHookSource;
22
+ // The actual hook source code. This is a self-contained ES module
23
+ // that runs in Node's loader worker thread.
24
+ const HOOK_SOURCE = `
25
+ // ── Snapshot data (populated by initialize) ──
26
+ let entries; // Map<path, {offset, size, format}>
27
+ let packages; // Map<path, {type, main, directory}>
28
+ let blob; // Uint8Array
29
+ let appId;
30
+ let dirSet; // Set<path> for directory existence
31
+
32
+ const BUILTINS = new Set([
33
+ 'assert','assert/strict','async_hooks','buffer','child_process',
34
+ 'cluster','console','constants','crypto','dgram',
35
+ 'diagnostics_channel','dns','dns/promises','domain','events',
36
+ 'fs','fs/promises','http','http2','https','inspector',
37
+ 'inspector/promises','module','net','os','path','path/posix',
38
+ 'path/win32','perf_hooks','process','punycode','querystring',
39
+ 'readline','readline/promises','repl','stream','stream/consumers',
40
+ 'stream/promises','stream/web','string_decoder','sys','test',
41
+ 'timers','timers/promises','tls','trace_events','tty','url',
42
+ 'util','util/types','v8','vm','wasi','worker_threads','zlib',
43
+ 'sqlite',
44
+ ]);
45
+
46
+ function isBuiltin(s) {
47
+ if (s.startsWith('node:')) return true;
48
+ return BUILTINS.has(s);
49
+ }
50
+
51
+ function isSnapshotUrl(url) {
52
+ return url.startsWith('file:///snapshot/');
53
+ }
54
+
55
+ function urlToPath(url) {
56
+ if (!url.startsWith('file:///snapshot/')) return null;
57
+ return '/snapshot/' + url.slice('file:///snapshot/'.length);
58
+ }
59
+
60
+ function pathToUrl(p) {
61
+ return 'file://' + p;
62
+ }
63
+
64
+ function canonicalize(p) {
65
+ const parts = p.split('/');
66
+ const result = [];
67
+ for (const part of parts) {
68
+ if (part === '' || part === '.') continue;
69
+ if (part === '..') { result.pop(); continue; }
70
+ result.push(part);
71
+ }
72
+ return '/' + result.join('/');
73
+ }
74
+
75
+ function extname(p) {
76
+ const dot = p.lastIndexOf('.');
77
+ const slash = p.lastIndexOf('/');
78
+ if (dot <= slash) return '';
79
+ return p.slice(dot);
80
+ }
81
+
82
+ function dirname(p) {
83
+ return p.substring(0, p.lastIndexOf('/')) || '/';
84
+ }
85
+
86
+ const RESOLVE_EXTS = ['.js','.mjs','.cjs','.json','.node'];
87
+
88
+ function exists(p) {
89
+ return entries.has(p) || dirSet.has(p);
90
+ }
91
+
92
+ function isFile(p) {
93
+ return entries.has(p);
94
+ }
95
+
96
+ function isDir(p) {
97
+ return dirSet.has(p);
98
+ }
99
+
100
+ function tryFile(p) {
101
+ if (isFile(p)) return p;
102
+ for (const ext of RESOLVE_EXTS) {
103
+ if (isFile(p + ext)) return p + ext;
104
+ }
105
+ if (isDir(p)) {
106
+ const pjPath = p + '/package.json';
107
+ if (isFile(pjPath) && packages.has(pjPath)) {
108
+ const pkg = packages.get(pjPath);
109
+ if (pkg.main) {
110
+ const mainPath = canonicalize(p + '/' + pkg.main);
111
+ const resolved = tryFile(mainPath);
112
+ if (resolved) return resolved;
113
+ }
114
+ }
115
+ for (const ext of RESOLVE_EXTS) {
116
+ if (isFile(p + '/index' + ext)) return p + '/index' + ext;
117
+ }
118
+ }
119
+ return null;
120
+ }
121
+
122
+ function getFormat(p) {
123
+ const ext = extname(p);
124
+ if (ext === '.mjs') return 'module';
125
+ if (ext === '.cjs') return 'commonjs';
126
+ if (ext === '.json') return 'json';
127
+ if (ext === '.wasm') return 'wasm';
128
+ const entry = entries.get(p);
129
+ if (entry?.format === 'esm') return 'module';
130
+ if (entry?.format === 'cjs') return 'commonjs';
131
+ return 'commonjs';
132
+ }
133
+
134
+ // ── exports/imports resolution (Node algorithm) ──
135
+
136
+ const ESM_CONDS = ['import', 'node', 'default'];
137
+
138
+ function resolveTarget(target, conds) {
139
+ if (typeof target === 'string') return target;
140
+ if (target === null) return null;
141
+ if (Array.isArray(target)) {
142
+ for (const t of target) { const r = resolveTarget(t, conds); if (r) return r; }
143
+ return null;
144
+ }
145
+ if (typeof target === 'object') {
146
+ for (const c of conds) { if (c in target) return resolveTarget(target[c], conds); }
147
+ return null;
148
+ }
149
+ return null;
150
+ }
151
+
152
+ function resolveExportsMap(exportsVal, subpath, conds) {
153
+ if (exportsVal == null) return null;
154
+ if (typeof exportsVal === 'string') return subpath === '.' ? exportsVal : null;
155
+ if (Array.isArray(exportsVal)) return resolveTarget(exportsVal, conds);
156
+ if (typeof exportsVal !== 'object') return null;
157
+ const keys = Object.keys(exportsVal);
158
+ const isCondObj = keys.length > 0 && !keys[0].startsWith('.');
159
+ if (isCondObj) return subpath === '.' ? resolveTarget(exportsVal, conds) : null;
160
+ if (subpath in exportsVal) return resolveTarget(exportsVal[subpath], conds);
161
+ for (const key of keys) {
162
+ if (!key.includes('*')) continue;
163
+ const si = key.indexOf('*'), pre = key.slice(0, si), suf = key.slice(si + 1);
164
+ if (subpath.startsWith(pre) && subpath.endsWith(suf)) {
165
+ const matched = subpath.slice(pre.length, subpath.length - (suf.length || Infinity));
166
+ const t = resolveTarget(exportsVal[key], conds);
167
+ if (t && typeof t === 'string') return t.replace('*', matched);
168
+ }
169
+ }
170
+ return null;
171
+ }
172
+
173
+ function resolveImportsMap(importsVal, spec, conds) {
174
+ if (!importsVal || typeof importsVal !== 'object' || !spec.startsWith('#')) return null;
175
+ if (spec in importsVal) return resolveTarget(importsVal[spec], conds);
176
+ for (const key of Object.keys(importsVal)) {
177
+ if (!key.includes('*')) continue;
178
+ const si = key.indexOf('*'), pre = key.slice(0, si), suf = key.slice(si + 1);
179
+ if (spec.startsWith(pre) && spec.endsWith(suf)) {
180
+ const matched = spec.slice(pre.length, spec.length - (suf.length || Infinity));
181
+ const t = resolveTarget(importsVal[key], conds);
182
+ if (t && typeof t === 'string') return t.replace('*', matched);
183
+ }
184
+ }
185
+ return null;
186
+ }
187
+
188
+ function findPackageDir(filePath) {
189
+ let dir = dirname(filePath);
190
+ const root = '/snapshot/' + appId;
191
+ while (dir.startsWith(root)) {
192
+ const pj = dir + '/package.json';
193
+ if (packages.has(pj)) return packages.get(pj);
194
+ dir = dirname(dir);
195
+ }
196
+ return null;
197
+ }
198
+
199
+ export function initialize(data) {
200
+ entries = new Map(Object.entries(data.entries));
201
+ packages = new Map(Object.entries(data.packages));
202
+ blob = new Uint8Array(data.blob);
203
+ appId = data.appId;
204
+ dirSet = new Set(data.directories);
205
+ }
206
+
207
+ // In Node 24+, hooks handle both ESM and CJS resolution.
208
+ // For ESM: shortCircuit and let the load hook provide source.
209
+ // For CJS nested requires (context.conditions includes 'require'):
210
+ // let nextResolve fall through to Module._resolveFilename + _compile
211
+ // patches on the main thread, which can read from the snapshot.
212
+ // For CJS imported by ESM (top-level): shortCircuit so the load hook
213
+ // provides the source to the ESM translator.
214
+ function maybeShortCircuit(url, format, nextResolve, specifier, context) {
215
+ if (format === 'commonjs' && context.conditions && context.conditions.includes('require')) {
216
+ // Nested CJS require — let the main thread's _resolveFilename handle it
217
+ return nextResolve(specifier, context);
218
+ }
219
+ return { url, shortCircuit: true, format };
220
+ }
221
+
222
+ export function resolve(specifier, context, nextResolve) {
223
+ if (isBuiltin(specifier)) {
224
+ return nextResolve(specifier, context);
225
+ }
226
+
227
+ const parentUrl = context.parentURL;
228
+
229
+ // Only handle snapshot-parented resolution
230
+ if (!parentUrl || !isSnapshotUrl(parentUrl)) {
231
+ // Entry point or non-snapshot parent
232
+ if (specifier.startsWith('file:///snapshot/')) {
233
+ const snapPath = urlToPath(specifier);
234
+ if (snapPath && isFile(snapPath)) {
235
+ return maybeShortCircuit(specifier, getFormat(snapPath), nextResolve, specifier, context);
236
+ }
237
+ }
238
+ return nextResolve(specifier, context);
239
+ }
240
+
241
+ const parentPath = urlToPath(parentUrl);
242
+ if (!parentPath) return nextResolve(specifier, context);
243
+
244
+ // #-prefixed package imports
245
+ if (specifier.startsWith('#')) {
246
+ const pkg = findPackageDir(parentPath);
247
+ if (pkg) {
248
+ // Read full package.json to get imports field
249
+ const pjEntry = entries.get(pkg.directory + '/package.json');
250
+ if (pjEntry) {
251
+ const pjSource = new TextDecoder().decode(blob.slice(pjEntry.offset, pjEntry.offset + pjEntry.size));
252
+ const pjData = JSON.parse(pjSource);
253
+ if (pjData.imports) {
254
+ const resolved = resolveImportsMap(pjData.imports, specifier, ESM_CONDS);
255
+ if (resolved) {
256
+ const fullPath = canonicalize(pkg.directory + '/' + resolved);
257
+ const fileResolved = tryFile(fullPath);
258
+ if (fileResolved) {
259
+ return maybeShortCircuit(pathToUrl(fileResolved), getFormat(fileResolved), nextResolve, specifier, context);
260
+ }
261
+ }
262
+ }
263
+ }
264
+ }
265
+ return nextResolve(specifier, context);
266
+ }
267
+
268
+ // Relative specifier
269
+ if (specifier.startsWith('.') || specifier.startsWith('/')) {
270
+ const parentDir = dirname(parentPath);
271
+ const target = canonicalize(parentDir + '/' + specifier);
272
+ if (!target.startsWith('/snapshot/')) return nextResolve(specifier, context);
273
+ const resolved = tryFile(target);
274
+ if (resolved) {
275
+ return maybeShortCircuit(pathToUrl(resolved), getFormat(resolved), nextResolve, specifier, context);
276
+ }
277
+ throw new Error(
278
+ 'Cannot find module \\'' + specifier + '\\' imported from ' + parentUrl
279
+ );
280
+ }
281
+
282
+ // Bare specifier — walk node_modules
283
+ const pkgName = specifier.startsWith('@')
284
+ ? specifier.split('/').slice(0, 2).join('/')
285
+ : specifier.split('/')[0];
286
+ const subpath = '.' + specifier.slice(pkgName.length);
287
+
288
+ let searchDir = dirname(parentPath);
289
+ const snapRoot = '/snapshot/' + appId;
290
+
291
+ while (searchDir.startsWith(snapRoot)) {
292
+ const nmDir = searchDir + '/node_modules/' + pkgName;
293
+ if (isDir(nmDir)) {
294
+ const pkgPjPath = nmDir + '/package.json';
295
+ const pkgPj = packages.get(pkgPjPath);
296
+
297
+ // Read full package.json for exports
298
+ const pjEntry = entries.get(pkgPjPath);
299
+ let exportsVal = null;
300
+ if (pjEntry) {
301
+ try {
302
+ const pjSource = new TextDecoder().decode(blob.slice(pjEntry.offset, pjEntry.offset + pjEntry.size));
303
+ const pjData = JSON.parse(pjSource);
304
+ exportsVal = pjData.exports;
305
+ } catch {}
306
+ }
307
+
308
+ // If exports is present, use it exclusively (Node semantics)
309
+ if (exportsVal != null) {
310
+ const resolved = resolveExportsMap(exportsVal, subpath, ESM_CONDS);
311
+ if (resolved && typeof resolved === 'string') {
312
+ const fullPath = canonicalize(nmDir + '/' + resolved);
313
+ const fileResolved = tryFile(fullPath);
314
+ if (fileResolved) {
315
+ return maybeShortCircuit(pathToUrl(fileResolved), getFormat(fileResolved), nextResolve, specifier, context);
316
+ }
317
+ }
318
+ // exports present but couldn't resolve — do NOT fall back
319
+ return nextResolve(specifier, context);
320
+ }
321
+
322
+ // Legacy resolution (no exports)
323
+ if (subpath === '.') {
324
+ if (pkgPj?.main) {
325
+ const resolved = tryFile(canonicalize(nmDir + '/' + pkgPj.main));
326
+ if (resolved) {
327
+ return maybeShortCircuit(pathToUrl(resolved), getFormat(resolved), nextResolve, specifier, context);
328
+ }
329
+ }
330
+ const resolved = tryFile(nmDir + '/index');
331
+ if (resolved) {
332
+ return maybeShortCircuit(pathToUrl(resolved), getFormat(resolved), nextResolve, specifier, context);
333
+ }
334
+ } else {
335
+ const resolved = tryFile(canonicalize(nmDir + '/' + subpath.slice(2)));
336
+ if (resolved) {
337
+ return maybeShortCircuit(pathToUrl(resolved), getFormat(resolved), nextResolve, specifier, context);
338
+ }
339
+ }
340
+ return nextResolve(specifier, context);
341
+ }
342
+ searchDir = dirname(searchDir);
343
+ }
344
+
345
+ return nextResolve(specifier, context);
346
+ }
347
+
348
+ export function load(url, context, nextLoad) {
349
+ if (!isSnapshotUrl(url)) {
350
+ return nextLoad(url, context);
351
+ }
352
+
353
+ const snapPath = urlToPath(url);
354
+ if (!snapPath) return nextLoad(url, context);
355
+
356
+ const entry = entries.get(snapPath);
357
+ if (!entry) return nextLoad(url, context);
358
+
359
+ const sourceBytes = blob.slice(entry.offset, entry.offset + entry.size);
360
+ const source = new TextDecoder().decode(sourceBytes);
361
+ const format = getFormat(snapPath);
362
+
363
+ return { source, format, shortCircuit: true };
364
+ }
365
+ `;
366
+ //# sourceMappingURL=esm-hooks.js.map
@@ -0,0 +1,292 @@
1
+ "use strict";
2
+ /**
3
+ * Hakobu ESM Resolver
4
+ *
5
+ * Resolves ESM specifiers against the snapshot filesystem and provides
6
+ * module source + format for loading. This is the core resolution logic
7
+ * used by the ESM loader hooks.
8
+ *
9
+ * Resolution follows Node 24 semantics:
10
+ * 1. Built-in modules (node:*) → passthrough
11
+ * 2. Absolute/relative specifiers → resolve within snapshot
12
+ * 3. Bare specifiers → resolve through snapshot node_modules
13
+ * 4. file: URLs → convert to snapshot path and resolve
14
+ *
15
+ * Format determination:
16
+ * .mjs → 'module'
17
+ * .cjs → 'commonjs'
18
+ * .js → determined by nearest package.json "type" field
19
+ * .json → 'json'
20
+ * .wasm → 'wasm'
21
+ */
22
+ var __importDefault = (this && this.__importDefault) || function (mod) {
23
+ return (mod && mod.__esModule) ? mod : { "default": mod };
24
+ };
25
+ Object.defineProperty(exports, "__esModule", { value: true });
26
+ exports.ESMResolver = void 0;
27
+ const path_1 = __importDefault(require("path"));
28
+ const snapshot_path_1 = require("./snapshot-path");
29
+ const exports_resolver_1 = require("./exports-resolver");
30
+ // ─────────────────────────────────────────────────────────────────────
31
+ // Built-in detection
32
+ // ─────────────────────────────────────────────────────────────────────
33
+ const BUILTINS = new Set([
34
+ 'assert', 'assert/strict', 'async_hooks', 'buffer', 'child_process',
35
+ 'cluster', 'console', 'constants', 'crypto', 'dgram',
36
+ 'diagnostics_channel', 'dns', 'dns/promises', 'domain', 'events',
37
+ 'fs', 'fs/promises', 'http', 'http2', 'https', 'inspector',
38
+ 'inspector/promises', 'module', 'net', 'os', 'path', 'path/posix',
39
+ 'path/win32', 'perf_hooks', 'process', 'punycode', 'querystring',
40
+ 'readline', 'readline/promises', 'repl', 'stream', 'stream/consumers',
41
+ 'stream/promises', 'stream/web', 'string_decoder', 'sys', 'test',
42
+ 'timers', 'timers/promises', 'tls', 'trace_events', 'tty', 'url',
43
+ 'util', 'util/types', 'v8', 'vm', 'wasi', 'worker_threads', 'zlib',
44
+ 'sqlite',
45
+ ]);
46
+ function isBuiltin(specifier) {
47
+ if (specifier.startsWith('node:'))
48
+ return true;
49
+ return BUILTINS.has(specifier);
50
+ }
51
+ // ─────────────────────────────────────────────────────────────────────
52
+ // Format determination
53
+ // ─────────────────────────────────────────────────────────────────────
54
+ function determineFormat(snapshotPath, sfs) {
55
+ const ext = path_1.default.extname(snapshotPath);
56
+ // Extension-based (definitive)
57
+ if (ext === '.mjs')
58
+ return 'module';
59
+ if (ext === '.cjs')
60
+ return 'commonjs';
61
+ if (ext === '.json')
62
+ return 'json';
63
+ if (ext === '.wasm')
64
+ return 'wasm';
65
+ // .js — use pre-resolved format from snapshot index
66
+ const format = sfs.getModuleFormat(snapshotPath);
67
+ if (format === 'esm')
68
+ return 'module';
69
+ if (format === 'cjs')
70
+ return 'commonjs';
71
+ // Fallback: check package boundary type
72
+ const boundary = sfs.getPackageBoundary(snapshotPath);
73
+ if (boundary?.type === 'module')
74
+ return 'module';
75
+ return 'commonjs';
76
+ }
77
+ // ─────────────────────────────────────────────────────────────────────
78
+ // Resolution extensions
79
+ // ─────────────────────────────────────────────────────────────────────
80
+ const RESOLVE_EXTENSIONS = ['.js', '.mjs', '.cjs', '.json', '.node'];
81
+ function tryResolveFile(snapshotPath, sfs) {
82
+ // Exact match
83
+ if (sfs.existsSync(snapshotPath) && sfs.statSync(snapshotPath).isFile()) {
84
+ return snapshotPath;
85
+ }
86
+ // Try extensions
87
+ for (const ext of RESOLVE_EXTENSIONS) {
88
+ const withExt = snapshotPath + ext;
89
+ if (sfs.existsSync(withExt) && sfs.statSync(withExt).isFile()) {
90
+ return withExt;
91
+ }
92
+ }
93
+ // Directory with index
94
+ if (sfs.existsSync(snapshotPath) && sfs.statSync(snapshotPath).isDirectory()) {
95
+ // Check package.json main
96
+ const pjPath = snapshotPath + '/package.json';
97
+ if (sfs.existsSync(pjPath)) {
98
+ const pj = sfs.getPackage(pjPath);
99
+ if (pj?.main) {
100
+ const mainPath = (0, snapshot_path_1.toCanonical)(snapshotPath + '/' + pj.main);
101
+ const resolved = tryResolveFile(mainPath, sfs);
102
+ if (resolved)
103
+ return resolved;
104
+ }
105
+ }
106
+ // Index file fallback
107
+ for (const ext of RESOLVE_EXTENSIONS) {
108
+ const indexPath = snapshotPath + '/index' + ext;
109
+ if (sfs.existsSync(indexPath))
110
+ return indexPath;
111
+ }
112
+ }
113
+ return null;
114
+ }
115
+ // ─────────────────────────────────────────────────────────────────────
116
+ // ESM Resolver
117
+ // ─────────────────────────────────────────────────────────────────────
118
+ class ESMResolver {
119
+ sfs;
120
+ constructor(sfs) {
121
+ this.sfs = sfs;
122
+ }
123
+ /**
124
+ * Resolve a specifier to a snapshot file: URL and format.
125
+ *
126
+ * @param specifier - The import specifier (e.g., './helper.js', 'express', 'node:fs')
127
+ * @param parentUrl - The file: URL of the importing module
128
+ * @returns ResolveResult or null if the specifier should be handled by Node's default loader
129
+ */
130
+ resolve(specifier, parentUrl) {
131
+ // 1. Built-ins — let Node handle
132
+ if (isBuiltin(specifier))
133
+ return null;
134
+ // 2. file: URL specifier
135
+ if (specifier.startsWith('file://')) {
136
+ const snapshotPath = (0, snapshot_path_1.fromFileUrl)(specifier);
137
+ if (snapshotPath) {
138
+ return this.resolveSnapshotPath(snapshotPath, specifier);
139
+ }
140
+ return null; // non-snapshot file: URL → Node handles it
141
+ }
142
+ // 3. #-prefixed package imports
143
+ if (specifier.startsWith('#')) {
144
+ return this.resolvePackageImports(specifier, parentUrl);
145
+ }
146
+ // 4. Relative specifier (./foo, ../bar, /snapshot/...)
147
+ if (specifier.startsWith('.') || specifier.startsWith('/')) {
148
+ return this.resolveRelative(specifier, parentUrl);
149
+ }
150
+ // 5. Bare specifier (package name)
151
+ return this.resolveBare(specifier, parentUrl);
152
+ }
153
+ /**
154
+ * Load a snapshot module's source and format.
155
+ *
156
+ * @param url - The resolved file: URL
157
+ * @returns LoadResult or null if the URL is not a snapshot module
158
+ */
159
+ load(url) {
160
+ const snapshotPath = (0, snapshot_path_1.fromFileUrl)(url);
161
+ if (!snapshotPath)
162
+ return null;
163
+ if (!this.sfs.existsSync(snapshotPath))
164
+ return null;
165
+ const source = this.sfs.readFileSync(snapshotPath).toString('utf8');
166
+ const format = determineFormat(snapshotPath, this.sfs);
167
+ return { source, format };
168
+ }
169
+ // ── Internal resolution ──
170
+ resolveSnapshotPath(snapshotPath, originalSpecifier) {
171
+ const resolved = tryResolveFile(snapshotPath, this.sfs);
172
+ if (!resolved)
173
+ return null;
174
+ return {
175
+ url: (0, snapshot_path_1.toFileUrl)(resolved),
176
+ snapshotPath: resolved,
177
+ format: determineFormat(resolved, this.sfs),
178
+ };
179
+ }
180
+ resolveRelative(specifier, parentUrl) {
181
+ // Convert parent URL to snapshot path
182
+ const parentSnapshotPath = (0, snapshot_path_1.fromFileUrl)(parentUrl);
183
+ if (!parentSnapshotPath)
184
+ return null; // parent is not in snapshot
185
+ // Resolve relative to parent directory
186
+ const parentDir = parentSnapshotPath.substring(0, parentSnapshotPath.lastIndexOf('/'));
187
+ const targetPath = (0, snapshot_path_1.toCanonical)(parentDir + '/' + specifier);
188
+ // Only resolve within snapshot
189
+ if (!targetPath.startsWith('/snapshot/'))
190
+ return null;
191
+ return this.resolveSnapshotPath(targetPath, specifier);
192
+ }
193
+ resolveBare(specifier, parentUrl) {
194
+ const parentSnapshotPath = (0, snapshot_path_1.fromFileUrl)(parentUrl);
195
+ if (!parentSnapshotPath)
196
+ return null;
197
+ const pkgName = specifier.startsWith('@')
198
+ ? specifier.split('/').slice(0, 2).join('/')
199
+ : specifier.split('/')[0];
200
+ const subpath = '.' + specifier.slice(pkgName.length);
201
+ let searchDir = parentSnapshotPath.substring(0, parentSnapshotPath.lastIndexOf('/'));
202
+ const snapshotRoot = '/snapshot/' + this.sfs.getAppId();
203
+ while (searchDir.startsWith(snapshotRoot)) {
204
+ const nmDir = searchDir + '/node_modules/' + pkgName;
205
+ if (this.sfs.existsSync(nmDir)) {
206
+ const pkgJsonPath = nmDir + '/package.json';
207
+ const pkg = this.sfs.existsSync(pkgJsonPath) ? this.sfs.getPackage(pkgJsonPath) : null;
208
+ // ── exports map resolution ──
209
+ // When "exports" is present, Node ONLY uses the exports map
210
+ // for bare specifier resolution. "main" is ignored.
211
+ if (pkg?.exports != null) {
212
+ const resolved = (0, exports_resolver_1.resolveExports)(pkg.exports, subpath, exports_resolver_1.ESM_CONDITIONS);
213
+ if (resolved && typeof resolved === 'string') {
214
+ const fullPath = (0, snapshot_path_1.toCanonical)(nmDir + '/' + resolved);
215
+ const fileResolved = tryResolveFile(fullPath, this.sfs);
216
+ if (fileResolved) {
217
+ return {
218
+ url: (0, snapshot_path_1.toFileUrl)(fileResolved),
219
+ snapshotPath: fileResolved,
220
+ format: determineFormat(fileResolved, this.sfs),
221
+ };
222
+ }
223
+ }
224
+ // exports map present but resolution failed — do NOT fall
225
+ // back to main/index (Node doesn't). Return null so the
226
+ // diagnostic layer can report the error.
227
+ return null;
228
+ }
229
+ // ── Legacy resolution (no exports map) ──
230
+ if (subpath === '.') {
231
+ if (pkg?.main) {
232
+ const mainResolved = tryResolveFile((0, snapshot_path_1.toCanonical)(nmDir + '/' + pkg.main), this.sfs);
233
+ if (mainResolved) {
234
+ return {
235
+ url: (0, snapshot_path_1.toFileUrl)(mainResolved),
236
+ snapshotPath: mainResolved,
237
+ format: determineFormat(mainResolved, this.sfs),
238
+ };
239
+ }
240
+ }
241
+ const indexResolved = tryResolveFile(nmDir + '/index', this.sfs);
242
+ if (indexResolved) {
243
+ return {
244
+ url: (0, snapshot_path_1.toFileUrl)(indexResolved),
245
+ snapshotPath: indexResolved,
246
+ format: determineFormat(indexResolved, this.sfs),
247
+ };
248
+ }
249
+ }
250
+ else {
251
+ const subResolved = tryResolveFile((0, snapshot_path_1.toCanonical)(nmDir + '/' + subpath.slice(2)), this.sfs);
252
+ if (subResolved) {
253
+ return {
254
+ url: (0, snapshot_path_1.toFileUrl)(subResolved),
255
+ snapshotPath: subResolved,
256
+ format: determineFormat(subResolved, this.sfs),
257
+ };
258
+ }
259
+ }
260
+ return null;
261
+ }
262
+ searchDir = searchDir.substring(0, searchDir.lastIndexOf('/'));
263
+ }
264
+ return null;
265
+ }
266
+ // ── #imports resolution ──
267
+ resolvePackageImports(specifier, parentUrl) {
268
+ const parentSnapshotPath = (0, snapshot_path_1.fromFileUrl)(parentUrl);
269
+ if (!parentSnapshotPath)
270
+ return null;
271
+ // Find the package boundary for the importing file
272
+ const boundary = this.sfs.getPackageBoundary(parentSnapshotPath);
273
+ if (!boundary?.imports)
274
+ return null;
275
+ const resolved = (0, exports_resolver_1.resolveImports)(boundary.imports, specifier, exports_resolver_1.ESM_CONDITIONS);
276
+ if (!resolved)
277
+ return null;
278
+ // Resolved target is relative to the package directory
279
+ const fullPath = (0, snapshot_path_1.toCanonical)(boundary.directory + '/' + resolved);
280
+ const fileResolved = tryResolveFile(fullPath, this.sfs);
281
+ if (fileResolved) {
282
+ return {
283
+ url: (0, snapshot_path_1.toFileUrl)(fileResolved),
284
+ snapshotPath: fileResolved,
285
+ format: determineFormat(fileResolved, this.sfs),
286
+ };
287
+ }
288
+ return null;
289
+ }
290
+ }
291
+ exports.ESMResolver = ESMResolver;
292
+ //# sourceMappingURL=esm-resolver.js.map