clojurific 0.12.1 → 0.12.3

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 (126) hide show
  1. package/README.md +3 -2
  2. package/cljf/cli.js +3 -2
  3. package/cljf/java.js +2 -1
  4. package/cljf/launcher.js +20 -11
  5. package/package.json +2 -2
  6. package/vite-plugin-cljs/index.js +77 -22
  7. package/compiler/deps.edn +0 -9
  8. package/compiler/src/main/cljs/cljs/analyzer/passes/and_or.cljc +0 -118
  9. package/compiler/src/main/cljs/cljs/analyzer/passes/lite.cljc +0 -32
  10. package/compiler/src/main/cljs/cljs/analyzer/passes.cljc +0 -32
  11. package/compiler/src/main/cljs/cljs/bootstrap_nodejs.js +0 -154
  12. package/compiler/src/main/cljs/cljs/core/specs/alpha.cljc +0 -272
  13. package/compiler/src/main/cljs/cljs/core/specs/alpha.cljs +0 -10
  14. package/compiler/src/main/cljs/cljs/core.cljs +0 -13194
  15. package/compiler/src/main/cljs/cljs/esm/goog/array.js +0 -61
  16. package/compiler/src/main/cljs/cljs/esm/goog/math.js +0 -1846
  17. package/compiler/src/main/cljs/cljs/esm/goog/object.js +0 -80
  18. package/compiler/src/main/cljs/cljs/esm/goog/string.js +0 -192
  19. package/compiler/src/main/cljs/cljs/esm/goog/userAgent/product.js +0 -10
  20. package/compiler/src/main/cljs/cljs/esm/goog.js +0 -90
  21. package/compiler/src/main/cljs/cljs/esm/karma.cljs +0 -103
  22. package/compiler/src/main/cljs/cljs/esm/lazy.clj +0 -51
  23. package/compiler/src/main/cljs/cljs/esm/lazy.cljs +0 -49
  24. package/compiler/src/main/cljs/cljs/esm/node_test.cljs +0 -21
  25. package/compiler/src/main/cljs/cljs/esm/repl_runtime.cljs +0 -353
  26. package/compiler/src/main/cljs/cljs/externs.js +0 -27
  27. package/compiler/src/main/cljs/cljs/imul.js +0 -11
  28. package/compiler/src/main/cljs/cljs/js.clj +0 -24
  29. package/compiler/src/main/cljs/cljs/js.cljs +0 -1432
  30. package/compiler/src/main/cljs/cljs/loader.cljs +0 -107
  31. package/compiler/src/main/cljs/cljs/main.clj +0 -67
  32. package/compiler/src/main/cljs/cljs/math.cljs +0 -869
  33. package/compiler/src/main/cljs/cljs/module_deps.js +0 -250
  34. package/compiler/src/main/cljs/cljs/nodejs.cljs +0 -27
  35. package/compiler/src/main/cljs/cljs/nodejs_externs.js +0 -3
  36. package/compiler/src/main/cljs/cljs/nodejscli.cljs +0 -22
  37. package/compiler/src/main/cljs/cljs/pprint.cljc +0 -167
  38. package/compiler/src/main/cljs/cljs/pprint.cljs +0 -3325
  39. package/compiler/src/main/cljs/cljs/proxy/impl.cljs +0 -32
  40. package/compiler/src/main/cljs/cljs/proxy.cljs +0 -184
  41. package/compiler/src/main/cljs/cljs/reader.clj +0 -18
  42. package/compiler/src/main/cljs/cljs/reader.cljs +0 -214
  43. package/compiler/src/main/cljs/cljs/repl.cljs +0 -206
  44. package/compiler/src/main/cljs/cljs/source_map/base64.cljs +0 -25
  45. package/compiler/src/main/cljs/cljs/source_map/base64_vlq.cljs +0 -102
  46. package/compiler/src/main/cljs/cljs/source_map.cljs +0 -305
  47. package/compiler/src/main/cljs/cljs/spec/alpha.cljc +0 -564
  48. package/compiler/src/main/cljs/cljs/spec/alpha.cljs +0 -1510
  49. package/compiler/src/main/cljs/cljs/spec/gen/alpha.cljc +0 -68
  50. package/compiler/src/main/cljs/cljs/spec/gen/alpha.cljs +0 -183
  51. package/compiler/src/main/cljs/cljs/spec/test/alpha.cljc +0 -329
  52. package/compiler/src/main/cljs/cljs/spec/test/alpha.cljs +0 -380
  53. package/compiler/src/main/cljs/cljs/stacktrace.cljc +0 -578
  54. package/compiler/src/main/cljs/cljs/test.cljc +0 -458
  55. package/compiler/src/main/cljs/cljs/test.cljs +0 -606
  56. package/compiler/src/main/cljs/clojure/browser/dom.cljs +0 -152
  57. package/compiler/src/main/cljs/clojure/browser/event.cljs +0 -101
  58. package/compiler/src/main/cljs/clojure/browser/net.cljs +0 -181
  59. package/compiler/src/main/cljs/clojure/browser/repl/preload.cljs +0 -13
  60. package/compiler/src/main/cljs/clojure/browser/repl.cljs +0 -283
  61. package/compiler/src/main/cljs/clojure/core/protocols.cljs +0 -29
  62. package/compiler/src/main/cljs/clojure/core/reducers.cljs +0 -312
  63. package/compiler/src/main/cljs/clojure/data.cljs +0 -162
  64. package/compiler/src/main/cljs/clojure/datafy.cljs +0 -63
  65. package/compiler/src/main/cljs/clojure/edn.cljs +0 -55
  66. package/compiler/src/main/cljs/clojure/reflect.cljs +0 -57
  67. package/compiler/src/main/cljs/clojure/set.cljs +0 -165
  68. package/compiler/src/main/cljs/clojure/string.cljs +0 -290
  69. package/compiler/src/main/cljs/clojure/walk.cljs +0 -98
  70. package/compiler/src/main/cljs/clojure/zip.cljs +0 -291
  71. package/compiler/src/main/cljs/process/env.cljs +0 -12
  72. package/compiler/src/main/cljs/shadow/resource.clj +0 -60
  73. package/compiler/src/main/cljs/shadow/resource.cljs +0 -10
  74. package/compiler/src/main/clojure/cljs/analyzer/api.cljc +0 -299
  75. package/compiler/src/main/clojure/cljs/analyzer/impl/namespaces.cljc +0 -68
  76. package/compiler/src/main/clojure/cljs/analyzer/impl.cljc +0 -59
  77. package/compiler/src/main/clojure/cljs/analyzer/macros.clj +0 -57
  78. package/compiler/src/main/clojure/cljs/analyzer/utils.clj +0 -36
  79. package/compiler/src/main/clojure/cljs/analyzer.cljc +0 -5292
  80. package/compiler/src/main/clojure/cljs/build/api.clj +0 -309
  81. package/compiler/src/main/clojure/cljs/cli.clj +0 -812
  82. package/compiler/src/main/clojure/cljs/closure.clj +0 -3440
  83. package/compiler/src/main/clojure/cljs/compiler/api.clj +0 -101
  84. package/compiler/src/main/clojure/cljs/compiler/macros.clj +0 -16
  85. package/compiler/src/main/clojure/cljs/compiler.cljc +0 -2748
  86. package/compiler/src/main/clojure/cljs/core/macros.clj +0 -43
  87. package/compiler/src/main/clojure/cljs/core/server.clj +0 -167
  88. package/compiler/src/main/clojure/cljs/core.cljc +0 -3719
  89. package/compiler/src/main/clojure/cljs/env/macros.clj +0 -37
  90. package/compiler/src/main/clojure/cljs/env.cljc +0 -102
  91. package/compiler/src/main/clojure/cljs/esm/repl/nrepl.clj +0 -151
  92. package/compiler/src/main/clojure/cljs/esm/repl.clj +0 -878
  93. package/compiler/src/main/clojure/cljs/esm.clj +0 -987
  94. package/compiler/src/main/clojure/cljs/externs/default.edn +0 -1549
  95. package/compiler/src/main/clojure/cljs/externs.clj +0 -479
  96. package/compiler/src/main/clojure/cljs/foreign/node.clj +0 -207
  97. package/compiler/src/main/clojure/cljs/instant.clj +0 -54
  98. package/compiler/src/main/clojure/cljs/js_deps.cljc +0 -412
  99. package/compiler/src/main/clojure/cljs/module_graph.cljc +0 -402
  100. package/compiler/src/main/clojure/cljs/repl/bootstrap.clj +0 -53
  101. package/compiler/src/main/clojure/cljs/repl/browser.clj +0 -540
  102. package/compiler/src/main/clojure/cljs/repl/node.clj +0 -253
  103. package/compiler/src/main/clojure/cljs/repl/node_repl.js +0 -114
  104. package/compiler/src/main/clojure/cljs/repl/reflect.clj +0 -85
  105. package/compiler/src/main/clojure/cljs/repl/server.clj +0 -236
  106. package/compiler/src/main/clojure/cljs/repl.cljc +0 -1615
  107. package/compiler/src/main/clojure/cljs/server/browser.clj +0 -54
  108. package/compiler/src/main/clojure/cljs/server/node.clj +0 -54
  109. package/compiler/src/main/clojure/cljs/source_map/base64.clj +0 -28
  110. package/compiler/src/main/clojure/cljs/source_map/base64_vlq.clj +0 -104
  111. package/compiler/src/main/clojure/cljs/source_map.clj +0 -369
  112. package/compiler/src/main/clojure/cljs/support.cljc +0 -18
  113. package/compiler/src/main/clojure/cljs/tagged_literals.cljc +0 -93
  114. package/compiler/src/main/clojure/cljs/util.cljc +0 -420
  115. package/compiler/src/main/clojure/cljs/vendor/bridge.clj +0 -42
  116. package/compiler/src/main/clojure/cljs/vendor/clojure/data/json.clj +0 -809
  117. package/compiler/src/main/clojure/cljs/vendor/clojure/tools/reader/default_data_readers.clj +0 -303
  118. package/compiler/src/main/clojure/cljs/vendor/clojure/tools/reader/edn.clj +0 -440
  119. package/compiler/src/main/clojure/cljs/vendor/clojure/tools/reader/impl/commons.clj +0 -131
  120. package/compiler/src/main/clojure/cljs/vendor/clojure/tools/reader/impl/errors.clj +0 -214
  121. package/compiler/src/main/clojure/cljs/vendor/clojure/tools/reader/impl/inspect.clj +0 -91
  122. package/compiler/src/main/clojure/cljs/vendor/clojure/tools/reader/impl/utils.clj +0 -127
  123. package/compiler/src/main/clojure/cljs/vendor/clojure/tools/reader/reader_types.clj +0 -431
  124. package/compiler/src/main/clojure/cljs/vendor/clojure/tools/reader.clj +0 -1035
  125. package/compiler/src/main/clojure/cljs/vendor/cognitect/transit.clj +0 -479
  126. /package/{compiler/no-clojurescript → no-clojurescript}/deps.edn +0 -0
package/README.md CHANGED
@@ -5,8 +5,9 @@ ClojureScript compiled to ES modules, bundled by Vite.
5
5
  [Clojurific](https://github.com/WhimsicalCode/clojurific) is a fork of
6
6
  ClojureScript whose `:module-format :esm` compiles every namespace to an ES
7
7
  module, leaving bundling, minification, npm packages and TypeScript to Vite,
8
- without the Google Closure Compiler. This package has the compiler, the `cljf`
9
- command, a Vite plugin with hot reloading, and a Karma adapter. It needs
8
+ without the Google Closure Compiler. This package has the `cljf` command, a
9
+ Vite plugin with hot reloading, and a Karma adapter; `cljf` gets the compiler,
10
+ `com.whimsical/clojurific`, from Clojars. It needs
10
11
  Node.js 20 or later and Java 17 or later, not the Clojure CLI.
11
12
 
12
13
  Status: experimental. Versions are `0.<minor>.<release>`: `<minor>` is the
package/cljf/cli.js CHANGED
@@ -42,9 +42,10 @@ function parse(argv) {
42
42
 
43
43
  function run(command, args) {
44
44
  const child = spawn(command, args, { stdio: 'inherit' });
45
+ // forwarded: only a terminal signals the JVM too (SIGINT), not kill, an IDE
46
+ // or a process supervisor; a second SIGINT is harmless
45
47
  for (const signal of ['SIGINT', 'SIGTERM', 'SIGHUP']) {
46
- // the terminal sends SIGINT to the JVM too, other signals are forwarded
47
- process.on(signal, () => signal !== 'SIGINT' && child.kill(signal));
48
+ process.on(signal, () => child.kill(signal));
48
49
  }
49
50
  child.on('error', e => {
50
51
  console.error(`cljf: ${command}: ${e.message}`);
package/cljf/java.js CHANGED
@@ -203,7 +203,8 @@ export async function setupJava({
203
203
  await fs.mkdir(dir, { recursive: true });
204
204
  const tmp = await fs.mkdtemp(path.join(dir, '.setup-'));
205
205
  try {
206
- const archive = path.join(tmp, pkg.name);
206
+ // a name from the API, not a path
207
+ const archive = path.join(tmp, path.basename(pkg.name));
207
208
  try {
208
209
  await download(pkg.link, archive, { sha256: pkg.checksum, fetch });
209
210
  } catch (e) {
package/cljf/launcher.js CHANGED
@@ -4,7 +4,7 @@
4
4
  // Classpaths are cached in the project's .cljf/cpcache, like the Clojure
5
5
  // CLI's .cpcache, until a deps.edn they were resolved from changes.
6
6
  import { spawn } from 'node:child_process';
7
- import { createHash } from 'node:crypto';
7
+ import { createHash, randomBytes } from 'node:crypto';
8
8
  import { existsSync, readFileSync } from 'node:fs';
9
9
  import fs from 'node:fs/promises';
10
10
  import path from 'node:path';
@@ -21,11 +21,18 @@ const packageRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '
21
21
 
22
22
  export const version = JSON.parse(readFileSync(path.join(packageRoot, 'package.json'), 'utf8')).version;
23
23
 
24
- // The compiler's sources: compiler/ in the npm package, the fork itself
25
- // (src/main/js is the package's root) when run from its repository
26
- export const compilerDir = existsSync(path.join(packageRoot, 'compiler', 'deps.edn'))
27
- ? path.join(packageRoot, 'compiler')
28
- : path.resolve(packageRoot, '../../..');
24
+ // Whether this is the npm package, which has no-clojurescript/, rather than
25
+ // the fork's repository (src/main/js is the package's root)
26
+ const packaged = existsSync(path.join(packageRoot, 'no-clojurescript', 'deps.edn'));
27
+
28
+ // The fork's repository, its compiler's sources, when run from it
29
+ export const compilerDir = packaged ? null : path.resolve(packageRoot, '../../..');
30
+
31
+ // The compiler: the npm package's version from Clojars (com.whimsical/clojurific
32
+ // is released with the package), or the fork's sources
33
+ export const compiler = packaged ? { ':mvn/version': version } : { ':local/root': compilerDir };
34
+
35
+ const noClojureScript = path.join(packaged ? packageRoot : compilerDir, 'no-clojurescript');
29
36
 
30
37
  const log = line => process.stderr.write(`${line}\n`);
31
38
 
@@ -37,7 +44,7 @@ export function normalizeAliases(aliases = []) {
37
44
 
38
45
  function cacheKey(aliases) {
39
46
  return createHash('sha256')
40
- .update(JSON.stringify({ version, compiler: compilerDir, aliases }))
47
+ .update(JSON.stringify({ version, compiler, aliases }))
41
48
  .digest('hex')
42
49
  .slice(0, 32);
43
50
  }
@@ -71,12 +78,14 @@ async function resolve({ project, aliases, java, cache, env, log }) {
71
78
  repository: env.CLJF_MAVEN_REPO || undefined,
72
79
  log,
73
80
  });
74
- const input = `${cache}.resolve.edn`;
75
- const output = `${cache}.resolve.json`;
81
+ // per process: another one may resolve the same classpath at the same time
82
+ const tmp = `${cache}.${process.pid}.${randomBytes(4).toString('hex')}`;
83
+ const input = `${tmp}.resolve.edn`;
84
+ const output = `${tmp}.resolve.json`;
76
85
  await fs.writeFile(input, edn({
77
86
  ':aliases': aliases,
78
- ':compiler': { ':local/root': compilerDir },
79
- ':no-clojurescript': { ':local/root': path.join(compilerDir, 'no-clojurescript') },
87
+ ':compiler': compiler,
88
+ ':no-clojurescript': { ':local/root': noClojureScript },
80
89
  ':output': output,
81
90
  }));
82
91
  log('cljf: resolving dependencies');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "clojurific",
3
- "version": "0.12.1",
3
+ "version": "0.12.3",
4
4
  "description": "ClojureScript compiled to ES modules, bundled by Vite",
5
5
  "license": "EPL-1.0",
6
6
  "repository": {
@@ -24,7 +24,7 @@
24
24
  "cljf/resolver/clojurific",
25
25
  "vite-plugin-cljs",
26
26
  "karma-esm",
27
- "compiler"
27
+ "no-clojurescript"
28
28
  ],
29
29
  "engines": {
30
30
  "node": ">=20"
@@ -7,7 +7,7 @@
7
7
  // TypeScript files they import.
8
8
  import { spawn } from 'node:child_process';
9
9
  import fs from 'node:fs/promises';
10
- import { existsSync } from 'node:fs';
10
+ import { existsSync, statSync } from 'node:fs';
11
11
  import path from 'node:path';
12
12
  import { createRequire } from 'node:module';
13
13
  import { pathToFileURL } from 'node:url';
@@ -31,16 +31,51 @@ async function sourceNamespace(file) {
31
31
  return ns;
32
32
  }
33
33
 
34
- // The ClojureScript sources pages load with module scripts
35
- async function pageSources(pages, root) {
36
- const sources = [];
37
- for (const page of pages) {
38
- const html = await fs.readFile(page, 'utf8');
39
- for (const [, src] of html.matchAll(/<script\b[^>]*\bsrc\s*=\s*["']([^"'?#]+\.clj[sc])["'][^>]*>/gi)) {
40
- sources.push(src.startsWith('/') ? path.join(root, src) : path.resolve(path.dirname(page), src));
34
+ const SCRIPT_SRC = /<script\b[^>]*\bsrc\s*=\s*["']([^"']+)["']/gi;
35
+ // import "x", import x from "x", export … from "x", import("x")
36
+ const IMPORT = /(?:\bimport\s*(?:[\w$*{}\s,]+\bfrom\s*)?|\bexport\s*[\w$*{}\s,]+\bfrom\s*|\bimport\s*\(\s*)["']([^"']+)["']/g;
37
+ const SCRIPT_FILE = /\.(?:[cm]?[jt]sx?)$/;
38
+ // extensionless imports, as TypeScript projects write them
39
+ const SCRIPT_SUFFIXES = ['', '.ts', '.tsx', '.js', '.jsx', '.mjs', '/index.ts', '/index.js'];
40
+
41
+ // The file a page's script or a module's import names: root-absolute or
42
+ // relative paths, not packages or aliases, which the bundler resolves
43
+ function importedFile(spec, from, root) {
44
+ const file = spec.replace(/[?#].*$/, '');
45
+ if (!file.startsWith('/') && !file.startsWith('.')) return null;
46
+ return file.startsWith('/') ? path.join(root, file) : path.resolve(path.dirname(from), file);
47
+ }
48
+
49
+ // The ClojureScript sources the entries (pages and JavaScript or TypeScript
50
+ // modules) load: the pages' scripts and the modules' imports, followed through
51
+ // the project's modules
52
+ async function entrySources(entries, root) {
53
+ const sources = new Set();
54
+ const seen = new Set();
55
+ const queue = [...entries];
56
+ while (queue.length) {
57
+ const file = queue.shift();
58
+ if (seen.has(file) || file.includes(`${path.sep}node_modules${path.sep}`)) continue;
59
+ seen.add(file);
60
+ let code;
61
+ try {
62
+ code = await fs.readFile(file, 'utf8');
63
+ } catch (e) {
64
+ continue;
65
+ }
66
+ for (const [, spec] of code.matchAll(file.endsWith('.html') ? SCRIPT_SRC : IMPORT)) {
67
+ const target = importedFile(spec, file, root);
68
+ if (!target) continue;
69
+ if (SOURCE_FILE.test(target)) {
70
+ if (existsSync(target)) sources.add(target);
71
+ } else {
72
+ const module = SCRIPT_SUFFIXES.map(suffix => target + suffix)
73
+ .find(f => SCRIPT_FILE.test(f) && existsSync(f) && !statSync(f).isDirectory());
74
+ if (module) queue.push(module);
75
+ }
41
76
  }
42
77
  }
43
- return [...new Set(sources)];
78
+ return [...sources];
44
79
  }
45
80
 
46
81
  // Whether address is this machine's
@@ -73,14 +108,20 @@ async function commonJSPackage(root) {
73
108
  }
74
109
  }
75
110
 
76
- // A Rollup input (a file, files or {name: file}) as {name: absolute file}
111
+ // A Rollup input (a file, files or {name: file}) as {name: absolute file},
112
+ // files named by their path in the root without the extension, so pages with
113
+ // the same file name in different directories (about/index.html) keep apart
77
114
  function inputObject(input, root) {
78
115
  if (!input) return {};
79
116
  if (typeof input === 'object' && !Array.isArray(input)) {
80
117
  return Object.fromEntries(Object.entries(input).map(([name, file]) => [name, path.resolve(root, file)]));
81
118
  }
82
- return Object.fromEntries([].concat(input).map(file =>
83
- [path.basename(file, path.extname(file)), path.resolve(root, file)]));
119
+ return Object.fromEntries([].concat(input).map(file => {
120
+ const absolute = path.resolve(root, file);
121
+ const relative = path.relative(root, absolute);
122
+ const name = relative.startsWith('..') || path.isAbsolute(relative) ? path.basename(absolute) : relative;
123
+ return [name.slice(0, name.length - path.extname(name).length).split(path.sep).join('/'), absolute];
124
+ }));
84
125
  }
85
126
 
86
127
  function ednString(s) {
@@ -315,6 +356,13 @@ export default function cljs(options) {
315
356
  return (compiled ? path.relative(outputDir, file) : path.relative(cwd, file)).split(path.sep).join('/');
316
357
  }
317
358
 
359
+ // Whether a ClojureScript source may be served: in Vite's root or
360
+ // server.fs.allow
361
+ function servedSource(file) {
362
+ const dirs = [config.root, ...(config.server?.fs?.allow ?? [])].map(dir => path.resolve(dir));
363
+ return SOURCE_FILE.test(file) && dirs.some(dir => file.startsWith(dir + path.sep));
364
+ }
365
+
318
366
  // The compiled module of a ClojureScript source file: its namespace's in the
319
367
  // build info, or its munged name
320
368
  async function compiledModule(file) {
@@ -325,7 +373,8 @@ export default function cljs(options) {
325
373
  `${ns.split('.').map(part => part.replace(/-/g, '_')).join('/')}.js`;
326
374
  const module = path.join(outputDir, relative);
327
375
  if (!existsSync(module)) {
328
- throw new Error(`${ns} (${file}) isn't compiled: load it with a page's script, or add it to :main`);
376
+ throw new Error(`${ns} (${file}) isn't compiled: load it from a page's script or a module the pages ` +
377
+ 'import (through relative or root-absolute imports, restarting Vite after adding it), or add it to :main');
329
378
  }
330
379
  return module;
331
380
  }
@@ -372,8 +421,8 @@ export default function cljs(options) {
372
421
  // the project's page, an input of builds and the dev server's /
373
422
  const indexHtml = existsSync(path.join(root, 'index.html')) ? path.join(root, 'index.html') : null;
374
423
  const userInput = userConfig.build?.rolldownOptions?.input ?? userConfig.build?.rollupOptions?.input;
375
- const pages = Object.values(inputObject(userInput ?? indexHtml, root)).filter(f => f.endsWith('.html'));
376
- pageNamespaces = await Promise.all((await pageSources(pages, root)).map(sourceNamespace));
424
+ const entries = Object.values(inputObject(userInput ?? indexHtml, root));
425
+ pageNamespaces = await Promise.all((await entrySources(entries, root)).map(sourceNamespace));
377
426
  if (env.command === 'build' && !env.isPreview) {
378
427
  const start = Date.now();
379
428
  if (userConfig.build?.watch) {
@@ -452,14 +501,17 @@ export default function cljs(options) {
452
501
  // A ClojureScript source: its compiled module, as a module importing it
453
502
  // when serving, which a page loading it by its source's URL and the
454
503
  // modules importing it by its own share
455
- const file = source.split('?')[0];
504
+ const file = source.split(/[?#]/)[0];
456
505
  if (SOURCE_FILE.test(file) && !source.startsWith('\0')) {
506
+ // URLs are root-relative, files are only served from the project
457
507
  const candidates = [
458
- ...(path.isAbsolute(file) ? [file] : []),
459
508
  ...(file.startsWith('/') ? [path.join(root, file)] : []),
460
- ...(importer && !importer.startsWith('\0') ? [path.resolve(path.dirname(importer.split('?')[0]), file)] : []),
509
+ ...(importer && !importer.startsWith('\0') && !file.startsWith('/')
510
+ ? [path.resolve(path.dirname(importer.split('?')[0]), file)]
511
+ : []),
512
+ ...(path.isAbsolute(file) ? [file] : []),
461
513
  ];
462
- const found = candidates.find(f => existsSync(f));
514
+ const found = candidates.find(f => servedSource(f) && existsSync(f));
463
515
  if (!found) return null;
464
516
  return config.command === 'build' ? compiledModule(found) : '\0' + SOURCE + found;
465
517
  }
@@ -479,7 +531,9 @@ export default function cljs(options) {
479
531
 
480
532
  async load(id) {
481
533
  if (id.startsWith('\0' + SOURCE)) {
482
- const module = await compiledModule(id.slice(SOURCE.length + 1));
534
+ const file = id.slice(SOURCE.length + 1);
535
+ if (!servedSource(file)) this.error(`${file} is outside the project`);
536
+ const module = await compiledModule(file);
483
537
  return `import ${JSON.stringify(module)};\nexport * from ${JSON.stringify(module)};\n`;
484
538
  }
485
539
  // compiled namespaces with their source maps, to the ClojureScript sources
@@ -604,9 +658,10 @@ export default function cljs(options) {
604
658
  async handler(html, { filename }) {
605
659
  if (config.command !== 'serve') return html;
606
660
  const replacements = await Promise.all(
607
- [...html.matchAll(/(<script\b[^>]*\bsrc\s*=\s*["'])([^"'?#]+\.clj[sc])(["'])/gi)].map(async match => {
661
+ // with a query or fragment, which the compiled module's URL keeps
662
+ [...html.matchAll(/(<script\b[^>]*\bsrc\s*=\s*["'])([^"'?#]+\.clj[sc])([?#][^"']*)?(["'])/gi)].map(async match => {
608
663
  const file = match[2].startsWith('/') ? path.join(config.root, match[2]) : path.resolve(path.dirname(filename), match[2]);
609
- return [match[0], match[1] + devUrl(await compiledModule(file)) + match[3]];
664
+ return [match[0], match[1] + devUrl(await compiledModule(file)) + (match[3] ?? '') + match[4]];
610
665
  }));
611
666
  return replacements.reduce((result, [from, to]) => result.replace(from, to), html);
612
667
  },
package/compiler/deps.edn DELETED
@@ -1,9 +0,0 @@
1
- {:paths ["src/main/clojure" "src/main/cljs"],
2
- :deps
3
- {com.cognitect/transit-java {:mvn/version "1.0.362"},
4
- org.clojure/clojure {:mvn/version "1.12.6"},
5
- org.clojure/core.specs.alpha {:mvn/version "0.1.24"},
6
- org.clojure/google-closure-library
7
- {:mvn/version "0.0-20250515-f04e4c0e"},
8
- org.clojure/spec.alpha {:mvn/version "0.1.143"},
9
- org.clojure/tools.reader {:mvn/version "1.3.6"}}}
@@ -1,118 +0,0 @@
1
- ;; Copyright (c) Rich Hickey. All rights reserved.
2
- ;; The use and distribution terms for this software are covered by the
3
- ;; Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php)
4
- ;; which can be found in the file epl-v10.html at the root of this distribution.
5
- ;; By using this software in any fashion, you are agreeing to be bound by
6
- ;; the terms of this license.
7
- ;; You must not remove this notice, or any other, from this software.
8
-
9
- (ns cljs.analyzer.passes.and-or
10
- (:require [cljs.analyzer.passes :as passes]))
11
-
12
- (def simple-ops
13
- #{:var :js-var :local :invoke :const :host-field :host-call :js :quote})
14
-
15
- (defn ->expr-env [ast]
16
- (assoc-in ast [:env :context] :expr))
17
-
18
- (defn simple-op? [ast]
19
- (contains? simple-ops (:op ast)))
20
-
21
- (defn simple-test-expr?
22
- [{:keys [op] :as ast}]
23
- (boolean
24
- (and (simple-op? ast)
25
- ('#{boolean seq}
26
- (or (:tag ast)
27
- (when (#{:local :var} op)
28
- (-> ast :info :tag)))))))
29
-
30
- (defn single-binding-let? [ast]
31
- (and (= :let (:op ast))
32
- (= 1 (count (-> ast :bindings)))))
33
-
34
- (defn no-statements? [let-ast]
35
- (= [] (-> let-ast :body :statements)))
36
-
37
- (defn returns-if? [let-ast]
38
- (= :if (-> let-ast :body :ret :op)))
39
-
40
- (defn simple-test-binding-let? [ast]
41
- (and (single-binding-let? ast)
42
- (no-statements? ast)
43
- (simple-test-expr? (-> ast :bindings first :init))
44
- (returns-if? ast)))
45
-
46
- (defn test=then? [if-ast]
47
- ;; remove :env, if same, local will differ only by
48
- ;; :context (:expr | :statement)
49
- (= (dissoc (:test if-ast) :env)
50
- (dissoc (:then if-ast) :env)))
51
-
52
- (defn test=else? [if-ast]
53
- ;; remove :env, if same, local will differ only by
54
- ;; :context (:expr | :statement)
55
- (= (dissoc (:test if-ast) :env)
56
- (dissoc (:else if-ast) :env)))
57
-
58
- (defn simple-and? [ast]
59
- (and (simple-test-binding-let? ast)
60
- (test=else? (-> ast :body :ret))))
61
-
62
- (defn simple-or? [ast]
63
- (and (simple-test-binding-let? ast)
64
- (test=then? (-> ast :body :ret))))
65
-
66
- (defn optimizable-and? [ast]
67
- (and (simple-and? ast)
68
- (simple-test-expr? (-> ast :body :ret :then))))
69
-
70
- (defn optimizable-or? [ast]
71
- (and (simple-or? ast)
72
- (simple-test-expr? (-> ast :body :ret :else))))
73
-
74
- (defn remove-loop-let [fn-ast local]
75
- (update fn-ast :loop-lets
76
- (fn [loop-lets]
77
- (map
78
- (fn [m]
79
- (update m :params
80
- (fn [xs] (remove #(= local (:name %)) xs))))
81
- loop-lets))))
82
-
83
- (defn remove-local-pass [local]
84
- (fn [env ast opts]
85
- (cond-> (update-in ast [:env :locals] dissoc local)
86
- (= :fn (:op ast)) (remove-loop-let local))))
87
-
88
- (defn optimize-and [ast]
89
- (let [{:keys [init name]} (-> ast :bindings first)]
90
- {:op :js
91
- :env (:env ast)
92
- :segs ["((" ") && (" "))"]
93
- :args [init
94
- (passes/walk
95
- (->expr-env (-> ast :body :ret :then))
96
- [(remove-local-pass name)])]
97
- :form (:form ast)
98
- :children [:args]
99
- :tag 'boolean}))
100
-
101
- (defn optimize-or [ast]
102
- (let [{:keys [init name]} (-> ast :bindings first)]
103
- {:op :js
104
- :env (:env ast)
105
- :segs ["((" ") || (" "))"]
106
- :args [init
107
- (passes/walk
108
- (->expr-env (-> ast :body :ret :else))
109
- [(remove-local-pass name)])]
110
- :form (:form ast)
111
- :children [:args]
112
- :tag 'boolean}))
113
-
114
- (defn optimize [env ast _]
115
- (cond
116
- (optimizable-and? ast) (optimize-and ast)
117
- (optimizable-or? ast) (optimize-or ast)
118
- :else ast))
@@ -1,32 +0,0 @@
1
- ;; Copyright (c) Rich Hickey. All rights reserved.
2
- ;; The use and distribution terms for this software are covered by the
3
- ;; Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php)
4
- ;; which can be found in the file epl-v10.html at the root of this distribution.
5
- ;; By using this software in any fashion, you are agreeing to be bound by
6
- ;; the terms of this license.
7
- ;; You must not remove this notice, or any other, from this software.
8
-
9
- (ns cljs.analyzer.passes.lite
10
- (:refer-clojure :exclude [var?]))
11
-
12
- (defn var? [ast]
13
- (= :var (:op ast)))
14
-
15
- (def ctor->ctor-lite
16
- '{cljs.core/vector cljs.core/vector-lite
17
- cljs.core/vec cljs.core/vec-lite})
18
-
19
- (defn update-var [{:keys [name] :as ast}]
20
- (let [replacement (get ctor->ctor-lite name)]
21
- (-> ast
22
- (assoc :name replacement)
23
- (assoc-in [:info :name] replacement))))
24
-
25
- (defn replace-var? [ast]
26
- (and (var? ast)
27
- (contains? ctor->ctor-lite (:name ast))))
28
-
29
- (defn use-lite-types
30
- [env ast _]
31
- (cond-> ast
32
- (replace-var? ast) update-var))
@@ -1,32 +0,0 @@
1
- ;; Copyright (c) Rich Hickey. All rights reserved.
2
- ;; The use and distribution terms for this software are covered by the
3
- ;; Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php)
4
- ;; which can be found in the file epl-v10.html at the root of this distribution.
5
- ;; By using this software in any fashion, you are agreeing to be bound by
6
- ;; the terms of this license.
7
- ;; You must not remove this notice, or any other, from this software.
8
-
9
- (ns cljs.analyzer.passes)
10
-
11
- (defn apply-passes
12
- ([ast passes]
13
- (apply-passes ast passes nil))
14
- ([ast passes opts]
15
- (reduce
16
- (fn [ast pass]
17
- (pass (:env ast) ast opts))
18
- ast passes)))
19
-
20
- (defn walk
21
- ([ast passes]
22
- (walk ast passes nil))
23
- ([ast passes opts]
24
- (reduce
25
- (fn [ast child-k]
26
- (assoc ast
27
- child-k
28
- (let [child (get ast child-k)]
29
- (if (vector? child)
30
- (into [] (map #(walk % passes opts)) child)
31
- (walk child passes opts)))))
32
- (some-> ast (apply-passes passes opts)) (:children ast))))
@@ -1,154 +0,0 @@
1
- // Copyright 2013 The Closure Library Authors.
2
- //
3
- // Licensed under the Apache License, Version 2.0 (the "License");
4
- // you may not use this file except in compliance with the License.
5
- // You may obtain a copy of the License at
6
- //
7
- // http://www.apache.org/licenses/LICENSE-2.0
8
- //
9
- // Unless required by applicable law or agreed to in writing, software
10
- // distributed under the License is distributed on an "AS-IS" BASIS,
11
- // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
- // See the License for the specific language governing permissions and
13
- // limitations under the License.
14
-
15
- /**
16
- * @fileoverview A nodejs script for dynamically requiring Closure within
17
- * nodejs.
18
- *
19
- * Example of usage:
20
- * <code>
21
- * require('./bootstrap/nodejs')
22
- * goog.require('goog.ui.Component')
23
- * </code>
24
- *
25
- * This loads goog.ui.Component in the global scope.
26
- *
27
- * If you want to load custom libraries, you can require the custom deps file
28
- * directly. If your custom libraries introduce new globals, you may
29
- * need to run goog.nodeGlobalRequire to get them to load correctly.
30
- *
31
- * <code>
32
- * require('./path/to/my/deps.js')
33
- * goog.bootstrap.nodeJs.nodeGlobalRequire('./path/to/my/base.js')
34
- * goog.require('my.Class')
35
- * </code>
36
- *
37
- * @author nick@medium.com (Nick Santos)
38
- *
39
- * @nocompile
40
- */
41
-
42
- var fs = require("fs");
43
- var vm = require("vm");
44
- var path = require("path");
45
- var CLJS_ROOT = ".";
46
-
47
-
48
- /**
49
- * The goog namespace in the global scope.
50
- */
51
- global.goog = {};
52
-
53
-
54
- /**
55
- * Imports a script using Node's require() API.
56
- *
57
- * @param {string} src The script source.
58
- * @return {boolean} True if the script was imported, false otherwise.
59
- */
60
- global.CLOSURE_IMPORT_SCRIPT = function(src, opt_sourceText) {
61
- // if CLJS_ROOT has been rewritten (by REPLs) need to compute require path
62
- // so we can delete the old entry from the Node.js require cache
63
- if(CLJS_ROOT !== ".") {
64
- var cached = null;
65
- if(src.substring(0, 2) == "..") {
66
- cached = path.join(CLJS_ROOT, src.substring(3));
67
- } else {
68
- cached = path.join(CLJS_ROOT, "goog", src);
69
- }
70
- if(require.cache[cached]) delete require.cache[cached];
71
- }
72
-
73
- // Sources are always expressed relative to closure's base.js, but
74
- // require() is always relative to the current source.
75
- if (opt_sourceText === undefined) {
76
- var flags = null;
77
- if (goog.debugLoader_) {
78
- var dep = goog.debugLoader_.dependencies_[src];
79
- if (dep) {
80
- flags = dep.loadFlags;
81
- }
82
- } else {
83
- flags = goog.dependencies_.loadFlags[src];
84
- }
85
- if (flags && flags["foreign-lib"]) {
86
- nodeGlobalRequire(path.resolve(__dirname, "..", src));
87
- } else {
88
- require(path.join(".", "..", src));
89
- }
90
- } else {
91
- eval(opt_sourceText);
92
- }
93
- return true;
94
- };
95
-
96
-
97
- /**
98
- * Loads a file when using Closure's goog.require() API with goog.modules.
99
- *
100
- * @param {string} src The file source.
101
- * @return {string} The file contents.
102
- */
103
- global.CLOSURE_LOAD_FILE_SYNC = function(src) {
104
- return fs.readFileSync(
105
- path.resolve(__dirname, "..", src), {encoding: "utf-8"});
106
- };
107
-
108
-
109
- // Declared here so it can be used to require base.js
110
- function nodeGlobalRequire(file) {
111
- var _module = global.module,
112
- _exports = global.exports,
113
- exportedRequire = false;
114
-
115
- // to circumvent Node.js environment detection in bundled libraries
116
- global.module = undefined;
117
- global.exports = undefined;
118
-
119
- // to allow requires of Node.js libraries (i.e. platform libs) that
120
- // couldn't be bundled for some reason
121
- if(global.require == undefined) {
122
- exportedRequire = true;
123
- global.require = require;
124
- }
125
-
126
- vm.runInThisContext.call(global, fs.readFileSync(file), file);
127
-
128
- global.exports = _exports;
129
- global.module = _module;
130
-
131
- if(exportedRequire) {
132
- global.require = undefined;
133
- }
134
- }
135
-
136
-
137
- // Load Closure's base.js into memory. It is assumed base.js is in the
138
- // directory above this directory given this script's location in
139
- // bootstrap/nodejs.js.
140
- nodeGlobalRequire(path.resolve(__dirname, "..", "base.js"));
141
-
142
-
143
- /**
144
- * Bootstraps a file into the global scope.
145
- *
146
- * This is strictly for cases where normal require() won't work,
147
- * because the file declares global symbols with 'var' that need to
148
- * be added to the global scope.
149
- * @suppress {missingProvide}
150
- *
151
- * @param {string} file The path to the file.
152
- */
153
- goog.nodeGlobalRequire = nodeGlobalRequire;
154
-