├── .circleci └── config.yml ├── .github └── FUNDING.yml ├── .gitignore ├── CHANGELOG.md ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── build-all.sh ├── build-cli.sh ├── build-deps.sh ├── deps.edn ├── doc ├── esm.md ├── remote.md └── ssl.md ├── externs ├── browser.txt ├── infer-externs.txt ├── launcher-renderer.txt └── ui.txt ├── karma.conf.js ├── npm-run.js ├── out ├── azure-fn │ ├── .gitignore │ ├── .vscode │ │ └── extensions.json │ ├── host.json │ └── simple │ │ └── function.json ├── chrome-ext │ ├── .gitignore │ ├── browser-action.html │ └── icon.png ├── chrome-manifest.edn ├── cljs-tests │ └── .gitignore ├── demo-bootstrap │ └── .gitignore ├── demo-browser │ ├── .gitignore │ ├── index.src.html │ └── public │ │ ├── .gitignore │ │ ├── css │ │ └── foo.css │ │ ├── esm-auto.html │ │ ├── esm.html │ │ ├── ext.html │ │ ├── foo │ │ └── index.html │ │ └── ws.html ├── demo-closure-es6 │ └── public │ │ └── index.html ├── demo-closure │ └── public │ │ └── index.html ├── demo-foreign │ └── index.html ├── demo-graal │ └── .gitignore ├── demo-karma │ └── .gitignore ├── demo-library │ ├── .gitignore │ ├── package.json │ └── script.js ├── demo-now │ ├── .gitignore │ ├── now.json │ └── package.json ├── demo-npm │ ├── .gitignore │ └── script.js ├── demo-script-bundle │ └── .gitignore ├── demo-script │ ├── .gitignore │ ├── foo.js │ └── package.json ├── demo-selfhost │ ├── .gitignore │ └── public │ │ ├── index-worker.html │ │ └── index.html ├── demo-single │ └── .gitignore ├── demo-sm-test │ └── public │ │ └── index.html ├── demo-test-browser │ └── index.html ├── demo-test-dummy │ └── index.html ├── demo-test-node-fail │ └── .gitignore ├── demo-test-node │ └── .gitignore ├── demo-warnings │ └── .gitignore ├── esm-node │ ├── .gitignore │ └── package.json ├── node-repl-dev │ └── .gitignore ├── npm-web │ ├── .gitignore │ ├── index.html │ ├── package.json │ ├── src │ │ └── index.js │ └── webpack.config.js ├── webpack-bundle │ ├── .gitignore │ └── public │ │ └── index.html └── webpack-dll │ ├── .gitignore │ ├── a.js │ ├── b.js │ ├── dll-a.config.js │ ├── dll-b.config.js │ └── index.html ├── package-lock.json ├── package.json ├── packages ├── .gitignore ├── babel-worker │ ├── .gitignore │ ├── package-lock.json │ └── package.json ├── chrome-ext │ ├── .gitignore │ ├── chrome-manifest.edn │ ├── panel.html │ └── shadow-cljs.html ├── create-cljs-project │ ├── .gitignore │ ├── .npmignore │ ├── files │ │ ├── gitignore │ │ └── shadow-cljs.edn │ └── package.json ├── external-testing │ ├── .gitignore │ └── package.json ├── resolve-check │ ├── .gitignore │ ├── package.json │ ├── test.js │ └── tests.edn ├── shadow-cljs-jar │ ├── .gitignore │ ├── .npmignore │ ├── README.md │ ├── package.json │ ├── path.js │ ├── project.clj │ ├── src │ │ └── shadow │ │ │ └── cljs │ │ │ └── npm │ │ │ └── deps.clj │ └── test.edn ├── shadow-cljs │ ├── .babelrc │ ├── .gitignore │ ├── .npmignore │ ├── README.md │ ├── cli │ │ ├── default-config.edn │ │ └── runner.js │ ├── package-lock.json │ └── package.json ├── testing │ └── package.json └── ui │ ├── package-lock.json │ └── package.json ├── postcss.config.js ├── project.clj ├── shadow-cljs.edn ├── src ├── css │ └── ui.css ├── dev │ ├── build.clj │ ├── changelog.clj │ ├── data_readers.cljc │ ├── demo │ │ ├── always_load.cljs │ │ ├── azure │ │ │ └── simple.cljs │ │ ├── bootstrap_script.cljs │ │ ├── browser-externs.js │ │ ├── browser.clj │ │ ├── browser.cljs │ │ ├── browser_extra.cljs │ │ ├── browser_specs.cljs │ │ ├── cant_compile.cljs │ │ ├── chrome │ │ │ ├── bg.cljs │ │ │ ├── browser_action.cljs │ │ │ ├── content.cljs │ │ │ ├── manual_inject.cljs │ │ │ └── page_action.cljs │ │ ├── cjs.js │ │ ├── cljc.cljc │ │ ├── closure.cljs │ │ ├── dce.cljs │ │ ├── defn_error.clj │ │ ├── dev_setup.clj │ │ ├── dummy_cljc.cljc │ │ ├── dummy_plugin.clj │ │ ├── errors.cljs │ │ ├── es6.js │ │ ├── esm │ │ │ ├── a.cljs │ │ │ ├── b.cljs │ │ │ ├── c.cljs │ │ │ └── node.cljs │ │ ├── expo.cljs │ │ ├── foo-bar.cljs │ │ ├── foo.js │ │ ├── foreign-ext.js │ │ ├── foreign.cljs │ │ ├── fulcro_expo.cljs │ │ ├── graal.cljs │ │ ├── hooks.clj │ │ ├── http.clj │ │ ├── instrument.cljs │ │ ├── js_class.js │ │ ├── lib.cljs │ │ ├── macro.clj │ │ ├── macro.cljs │ │ ├── macro_dep.clj │ │ ├── mixed.cljc │ │ ├── more-es6.js │ │ ├── native.cljs │ │ ├── never_load.cljs │ │ ├── notify_plugin.clj │ │ ├── now.cljs │ │ ├── npm.cljs │ │ ├── ns.cljs │ │ ├── preload.cljs │ │ ├── protocol.cljs │ │ ├── prototype.js │ │ ├── read_cond.cljc │ │ ├── reagent.cljs │ │ ├── rel_require.cljs │ │ ├── repl.cljs │ │ ├── rn.cljs │ │ ├── rn_foo.cljs │ │ ├── rule-breaker.js │ │ ├── run_test.clj │ │ ├── script.cljs │ │ ├── selfhost │ │ │ ├── host.cljs │ │ │ ├── simple.cljs │ │ │ └── worker.cljs │ │ ├── sm_before.cljs │ │ ├── sm_main.cljs │ │ ├── stuff.cljs │ │ ├── test.md │ │ ├── test_fail.cljs │ │ ├── type.cljs │ │ ├── warnings.cljs │ │ ├── with_underscore.cljs │ │ ├── worker.cljs │ │ └── zombie.cljs │ ├── git_tags.clj │ ├── log4j.properties.shutup │ ├── repl.clj │ ├── shadow │ │ ├── insight │ │ │ ├── MarkdownDatafier.java │ │ │ ├── parser.clj │ │ │ ├── plugin.clj │ │ │ ├── remote_ext.cljc │ │ │ ├── remote_ext │ │ │ │ ├── clj.clj │ │ │ │ └── cljs.cljs │ │ │ ├── runtime.cljc │ │ │ ├── ui.cljs │ │ │ └── web.clj │ │ ├── remote_example_ws.clj │ │ └── resolve_check.cljs │ ├── shadow_test.clj │ └── user.clj ├── js │ ├── .babelrc │ ├── convert.sh │ └── demo │ │ └── myComponent.jsx ├── main │ ├── cljs │ │ ├── pprint_stubs.cljs │ │ ├── test_stubs.clj │ │ └── test_stubs.cljs │ ├── com │ │ └── google │ │ │ └── javascript │ │ │ └── jscomp │ │ │ ├── ShadowAccess.java │ │ │ ├── ShadowCompiler.java │ │ │ └── ShadowESModuleRewriter.java │ └── shadow │ │ ├── boot │ │ ├── browser.js │ │ ├── esm.js │ │ ├── npm_module.js │ │ ├── react-native.js │ │ ├── static.js │ │ └── worker.js │ │ ├── build.clj │ │ ├── build │ │ ├── api.clj │ │ ├── async.clj │ │ ├── babel.clj │ │ ├── cache.clj │ │ ├── classpath.clj │ │ ├── cljs_bridge.clj │ │ ├── cljs_hacks.cljc │ │ ├── closure.clj │ │ ├── closure │ │ │ ├── FindSurvivingRequireCalls.java │ │ │ ├── GlobalVars.java │ │ │ ├── GlobalsAsVar.java │ │ │ ├── JsInspector.java │ │ │ ├── NodeEnvInlinePass.java │ │ │ ├── NodeStuffInlinePass.java │ │ │ ├── ParserHelper.java │ │ │ ├── PropertyCollector.java │ │ │ ├── ReplaceCLJSConstants.java │ │ │ ├── ReplaceRequirePass.java │ │ │ ├── ShadowESMExports.java │ │ │ ├── ShadowESMImports.java │ │ │ └── SourceMapReport.java │ │ ├── compiler.clj │ │ ├── config.clj │ │ ├── css.clj │ │ ├── data.clj │ │ ├── js_support.clj │ │ ├── json_order_preserving.clj │ │ ├── log.clj │ │ ├── macros.clj │ │ ├── modules.clj │ │ ├── node.clj │ │ ├── npm.clj │ │ ├── ns_form.clj │ │ ├── output.clj │ │ ├── resolve.clj │ │ ├── resource.clj │ │ ├── targets │ │ │ ├── azure_app.clj │ │ │ ├── bootstrap.clj │ │ │ ├── browser.clj │ │ │ ├── browser_test.clj │ │ │ ├── chrome_extension.clj │ │ │ ├── esm.clj │ │ │ ├── esm_files.clj │ │ │ ├── expo.clj │ │ │ ├── external_boilerplate.js │ │ │ ├── external_index.clj │ │ │ ├── graaljs.clj │ │ │ ├── graaljs_bootstrap.js │ │ │ ├── karma.clj │ │ │ ├── node_library.clj │ │ │ ├── node_script.clj │ │ │ ├── node_test.clj │ │ │ ├── npm_module.clj │ │ │ ├── npm_module_goog_overrides.js │ │ │ ├── react_native.clj │ │ │ ├── shared.clj │ │ │ ├── single_file.clj │ │ │ ├── umd_exports.txt │ │ │ └── umd_exports_dev.txt │ │ ├── test.clj │ │ ├── test_util.clj │ │ └── warnings.clj │ │ ├── cli_util.cljc │ │ ├── cljs │ │ ├── bootstrap │ │ │ ├── browser.cljs │ │ │ ├── env.cljs │ │ │ └── node.cljs │ │ ├── build_report.clj │ │ ├── build_report │ │ │ └── ui.cljs │ │ ├── cli.clj │ │ ├── config_env.cljc │ │ ├── devtools │ │ │ ├── api.clj │ │ │ ├── cli.clj │ │ │ ├── cli_actual.clj │ │ │ ├── cli_info.clj │ │ │ ├── cli_opts.cljc │ │ │ ├── client │ │ │ │ ├── browser.cljs │ │ │ │ ├── browser_repl.cljs │ │ │ │ ├── console.cljs │ │ │ │ ├── env.cljs │ │ │ │ ├── hud.cljs │ │ │ │ ├── node.cljs │ │ │ │ ├── node_esm.cljs │ │ │ │ ├── node_repl.cljs │ │ │ │ ├── npm_module.cljs │ │ │ │ ├── react_native.cljs │ │ │ │ ├── shared.cljs │ │ │ │ └── websocket.cljs │ │ │ ├── cljs_specs.clj │ │ │ ├── config.clj │ │ │ ├── errors.clj │ │ │ ├── plugin_manager.clj │ │ │ ├── server.clj │ │ │ └── server │ │ │ │ ├── build_history.clj │ │ │ │ ├── cli_check.clj │ │ │ │ ├── common.clj │ │ │ │ ├── config_watch.clj │ │ │ │ ├── dev_http.clj │ │ │ │ ├── dev_http │ │ │ │ └── favicon.ico │ │ │ │ ├── env.clj │ │ │ │ ├── fs_watch.clj │ │ │ │ ├── npm_deps.clj │ │ │ │ ├── nrepl.clj │ │ │ │ ├── nrepl04.clj │ │ │ │ ├── nrepl_impl.clj │ │ │ │ ├── ns_explorer.clj │ │ │ │ ├── ns_explorer │ │ │ │ └── impl.clj │ │ │ │ ├── prepl.clj │ │ │ │ ├── relay_tcp.clj │ │ │ │ ├── reload_classpath.clj │ │ │ │ ├── reload_npm.clj │ │ │ │ ├── remote_ext.clj │ │ │ │ ├── repl_impl.clj │ │ │ │ ├── ring_gzip.clj │ │ │ │ ├── runtime.clj │ │ │ │ ├── socket_repl.clj │ │ │ │ ├── supervisor.clj │ │ │ │ ├── sync_db.clj │ │ │ │ ├── system_bus.clj │ │ │ │ ├── util.clj │ │ │ │ ├── web.clj │ │ │ │ ├── web │ │ │ │ ├── api.clj │ │ │ │ ├── common.clj │ │ │ │ └── resources │ │ │ │ │ └── img │ │ │ │ │ └── shadow-cljs.png │ │ │ │ ├── worker.clj │ │ │ │ └── worker │ │ │ │ └── impl.clj │ │ ├── externs │ │ │ ├── node.js │ │ │ ├── npm.js │ │ │ └── process.js │ │ ├── graaljs.clj │ │ ├── modern.cljc │ │ ├── modern.cljs │ │ ├── nashorn.clj │ │ ├── node_bootstrap.txt │ │ ├── npm │ │ │ ├── babel_worker.cljs │ │ │ ├── cli.cljs │ │ │ ├── client.cljs │ │ │ ├── create.cljs │ │ │ └── util.cljs │ │ ├── repl.clj │ │ ├── silence_default_loggers.clj │ │ ├── ui │ │ │ ├── components │ │ │ │ ├── build.cljs │ │ │ │ ├── build_status.cljs │ │ │ │ ├── builds.cljs │ │ │ │ ├── code-editor.css │ │ │ │ ├── code_editor.cljs │ │ │ │ ├── common.cljs │ │ │ │ ├── dashboard.cljs │ │ │ │ ├── inspect.cljs │ │ │ │ ├── repl.cljs │ │ │ │ └── runtimes.cljs │ │ │ ├── db │ │ │ │ ├── builds.cljs │ │ │ │ ├── explorer.cljs │ │ │ │ ├── generic.cljs │ │ │ │ ├── inspect.cljs │ │ │ │ └── relay_ws.cljs │ │ │ ├── main.cljs │ │ │ └── main.css │ │ └── util.clj │ │ ├── cljs_helpers.js │ │ ├── core_ext.clj │ │ ├── cursive_repl.clj │ │ ├── debug.clj │ │ ├── debug.cljs │ │ ├── esm.cljs │ │ ├── expo.cljs │ │ ├── expo │ │ ├── keep_awake.cljs │ │ └── keep_awake_async.cljs │ │ ├── html.clj │ │ ├── http │ │ ├── push_state.clj │ │ └── router.clj │ │ ├── insight.clj │ │ ├── js.js │ │ ├── js │ │ ├── babel.js │ │ └── external.js │ │ ├── json.cljs │ │ ├── jvm_log.clj │ │ ├── lazy.clj │ │ ├── lazy.cljs │ │ ├── loader.js │ │ ├── nrepl_debug.clj │ │ ├── react_native.cljs │ │ ├── remote │ │ ├── relay │ │ │ ├── api.cljc │ │ │ ├── local.clj │ │ │ └── simple_query.clj │ │ └── runtime │ │ │ ├── LimitWriter.java │ │ │ ├── api.cljc │ │ │ ├── clj │ │ │ └── local.clj │ │ │ ├── cljs │ │ │ ├── browser.cljs │ │ │ ├── js_builtins.cljs │ │ │ └── node.cljs │ │ │ ├── eval_support.clj │ │ │ ├── eval_support.cljs │ │ │ ├── explore_support.clj │ │ │ ├── obj_support.cljc │ │ │ ├── shared.cljc │ │ │ ├── tap_support.cljc │ │ │ ├── writer.clj │ │ │ └── writer.cljs │ │ ├── repl.clj │ │ ├── repl_ui.clj │ │ ├── resource.clj │ │ ├── resource.cljs │ │ ├── test.cljs │ │ ├── test │ │ ├── browser.cljs │ │ ├── env.clj │ │ ├── env.cljs │ │ ├── karma.cljs │ │ ├── node.cljs │ │ ├── remote_inject.cljs │ │ ├── repl.cljc │ │ └── workspaces.cljs │ │ ├── txt │ │ └── repl-help.txt │ │ ├── user.clj │ │ ├── util │ │ ├── FS.java │ │ └── FileWatcher.java │ │ └── ws_test.clj ├── repl │ ├── Test.java │ ├── app │ │ ├── page.cljs │ │ └── shared.cljs │ ├── bar.js │ ├── code_split │ │ ├── a.cljs │ │ ├── b.cljs │ │ ├── c.cljs │ │ └── externs.js │ ├── demo │ │ ├── http.clj │ │ └── test_dummy.cljs │ ├── index.js │ ├── react.externs.js │ ├── shadow │ │ ├── benchmark.clj │ │ ├── build │ │ │ ├── js_inspector_test.clj │ │ │ ├── targets │ │ │ │ └── foo_test.clj │ │ │ └── test_test.clj │ │ ├── chokidar.cljs │ │ ├── cljs │ │ │ ├── analyzer_test.clj │ │ │ ├── build_api_test.clj │ │ │ ├── build_test.clj │ │ │ ├── classpath_test.clj │ │ │ ├── closure_test.clj │ │ │ ├── deps_test.clj │ │ │ ├── devtools │ │ │ │ ├── FSTest.java │ │ │ │ ├── cli_test.clj │ │ │ │ └── nrepl_test.clj │ │ │ ├── devtools_test.clj │ │ │ ├── foreign_test.clj │ │ │ ├── modern_test.clj │ │ │ ├── release_snapshot_test.clj │ │ │ ├── repl_test.clj │ │ │ ├── resolve_test.clj │ │ │ ├── test_util.clj │ │ │ ├── ui_test.clj │ │ │ └── watch_test.clj │ │ ├── closure_test.clj │ │ ├── expo_test.clj │ │ ├── grove │ │ │ └── insight.cljs │ │ ├── insight │ │ │ └── example__in.clj │ │ ├── insight_test.clj │ │ ├── load_debug.clj │ │ └── undertow_test.clj │ ├── test.externs.js │ └── test │ │ ├── bar.cljs │ │ ├── empty.cljs │ │ ├── ext.js │ │ ├── perf.cljs │ │ └── snippet.cljs ├── test │ ├── circular │ │ ├── foo.cljs │ │ ├── main.cljs │ │ └── util │ │ │ └── lib.cljs │ ├── foo.js │ └── shadow │ │ ├── build │ │ ├── closure │ │ │ ├── ReplaceRequirePassTest.java │ │ │ └── SourceMapReportTest.java │ │ ├── npm_test.clj │ │ └── ns_form_test.clj │ │ ├── cli_util_test.clj │ │ └── undertow_test.clj └── ui-release │ └── shadow │ └── cljs │ ├── build_report │ └── dist │ │ └── css │ │ └── main.css │ └── ui │ └── dist │ ├── css │ └── .gitignore │ ├── favicon.ico │ └── img │ ├── shadow-cljs.png │ └── shadow-cljs.svg ├── tailwind.config.js ├── test-env └── node_modules │ ├── @scoped │ └── a │ │ ├── index.js │ │ └── package.json │ ├── browser-override │ ├── index.js │ ├── package.json │ └── web │ │ ├── dist │ │ ├── server.cjs │ │ └── web.cjs │ │ └── package.json │ ├── dep-a │ ├── index.js │ ├── node_modules │ │ ├── dep-b │ │ │ ├── index.js │ │ │ └── package.json │ │ └── dep-c │ │ │ ├── index.js │ │ │ └── package.json │ └── package.json │ ├── dir.js │ ├── main.js │ └── package.json │ ├── dyn-import │ ├── dynamic.js │ ├── index.js │ ├── package.json │ └── regular.js │ ├── entry-dir │ ├── foo │ │ └── index.js │ └── package.json │ ├── exports │ ├── foo.js │ ├── other │ │ └── foo.js │ └── package.json │ ├── extra-js-package-dir │ └── extra-package │ │ ├── index.js │ │ └── package.json │ ├── file-over-dir │ ├── foo.js │ ├── foo │ │ └── bar.js │ └── package.json │ ├── implicits │ ├── index.js │ └── package.json │ ├── lvl1 │ ├── index.js │ ├── node_modules │ │ └── lvl2 │ │ │ ├── index.js │ │ │ └── package.json │ └── package.json │ ├── lvl2 │ ├── index.js │ └── package.json │ ├── main-is-dir │ ├── lib │ │ └── index.js │ └── package.json │ ├── nested-but-not-really │ ├── bar.js │ ├── foo.js │ ├── index.js │ ├── nested │ │ └── package.json │ └── package.json │ ├── nested-pkg │ ├── just-index │ │ ├── index.js │ │ └── package.json │ ├── nested │ │ ├── main.js │ │ └── package.json │ ├── package.json │ └── relative │ │ └── index.js │ ├── pkg-a │ ├── index-browser.js │ ├── index.js │ ├── nested │ │ └── thing.js │ └── package.json │ ├── pkg-nested-override │ ├── dir │ │ ├── bar.js │ │ ├── foo.browser.js │ │ └── foo.js │ ├── index.js │ ├── package.json │ └── pkg-override.js │ └── with-assets │ ├── foo.css │ ├── index.js │ └── package.json ├── test-project ├── .gitignore ├── ci-run.sh ├── karma.conf.js ├── package.json ├── shadow-cljs.edn └── src │ └── main │ └── test │ ├── cjs.js │ ├── converted-esm.js │ ├── es6.js │ ├── esm_other.js │ ├── foo.cljs │ ├── infer_test.cljs │ ├── js_interop_test.cljs │ ├── reagent.cljs │ └── runnable.clj └── test ├── cjs ├── a-compiled.js ├── a.js ├── b.js ├── c.js ├── d.js ├── entry.js └── js-sm-test.js ├── closure-inputs ├── assigns.js ├── dummy.js ├── dummy.js.map └── node_env.js ├── dummy ├── circular-a.js ├── circular-b.js ├── react.dev.js └── react.min.js ├── es6 ├── babel.js ├── polyfill.js └── thing.js ├── react-dom.ext.js ├── react.ext.js └── resource-dir ├── deps.cljs ├── file-externs.js ├── file-min.js ├── file.js └── foo ├── bar.cljs ├── es6.js ├── externs.js └── goog.js /.circleci/config.yml: -------------------------------------------------------------------------------- 1 | # Clojure CircleCI 2.0 configuration file 2 | # 3 | # Check https://circleci.com/docs/2.0/language-clojure/ for more details 4 | # 5 | defaults: &defaults 6 | working_directory: ~/repo 7 | docker: 8 | - image: cimg/clojure:1.11.4-openjdk-21.0-browsers 9 | environment: 10 | LEIN_ROOT: "true" 11 | # Customize the JVM maximum heap limit 12 | JVM_OPTS: -Xmx3200m 13 | 14 | version: 2 15 | jobs: 16 | build: 17 | <<: *defaults 18 | steps: 19 | - checkout 20 | 21 | - restore_cache: 22 | keys: 23 | - m2-deps-v2-{{ checksum "project.clj" }} 24 | - m2-deps-v2- 25 | 26 | - run: sh build-deps.sh 27 | 28 | - run: lein do test, install, run -m shadow.cljs.devtools.cli release cli 29 | 30 | - run: cd packages/shadow-cljs; npm install 31 | 32 | - run: cd test-project; sh ci-run.sh 33 | 34 | - save_cache: 35 | paths: 36 | - ~/.m2 37 | key: m2-deps-v2-{{ checksum "project.clj" }} 38 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: thheller # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] 4 | patreon: # thheller # Replace with a single Patreon username 5 | open_collective: # Replace with a single Open Collective username 6 | ko_fi: # Replace with a single Ko-fi username 7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 | custom: ["https://strike.me/thheller", "https://www.paypal.me/thheller"] 9 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /ssl 2 | /out/TestCRNA 3 | /out/ExpoTest 4 | /out/production 5 | /src/ui-release/**/*.js 6 | target/ 7 | node_modules/ 8 | classes/ 9 | checkouts/ 10 | cljs-runtime/ 11 | js/ 12 | !src/main/shadow/js 13 | !packages/launcher/web/css 14 | /public/assets 15 | /wiki 16 | /book 17 | /blog 18 | /examples 19 | /src/gen 20 | pom.xml 21 | pom.xml.asc 22 | *.iml 23 | *.jar 24 | *.js.map 25 | *.class 26 | .cpcache 27 | .cljs-cache 28 | .shadow-cljs 29 | .cljs-repl 30 | .cljs_node_repl 31 | .idea 32 | .lein-* 33 | .nrepl-* 34 | /doc/codox 35 | /tmp 36 | /ssl 37 | .DS_Store 38 | yarn.lock 39 | package-lock.json 40 | !/package-lock.json 41 | /package.json 42 | *.log 43 | src/dev/shadow-css-index.edn 44 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | ## Process 4 | 5 | Most of the standard open-source and Github workflow applies. 6 | 7 | Pull requests are welcome, and maintainers reserve the right to decide what ends up in the codebase. If you want to increase the chances your contribution will make it into the codebase, open an issue describing the features or changes you'd like included before making a PR. Once a PR is opened, maintainers may still request changes. 8 | 9 | `shadow-cljs` is built with extensibility in mind so most enhancements and features can probably be built without touching the main project. Ideally start with simple functions in a library. Not only does this make it easier to assess what is actually done, it might also open it up to inclusion in other projects. 10 | 11 | ## Setting up 12 | 13 | Make a fork of the repo and clone your fork onto your local machine. 14 | 15 | Have a look around! Since `shadow-cljs` is a build tool, there are multiple build configurations in the project's own `shadow-cljs.edn` that you can use to debug and develop features. 16 | 17 | ## Starting a REPL 18 | 19 | Development is almost entirely REPL-based, so when you're ready to dive in, you'll want to start a REPL. 20 | 21 | Starting one and connecting the editor of your choice should be the same as any Leiningen-based project. 22 | 23 | When all else fails, this should work with all nREPL compatible editors: 24 | 25 | 1. `lein with-profiles +cljs repl` 26 | 2. Establish remote nREPL connection to port in `.nrepl-port` 27 | 3. Run `(require 'repl) (repl/go)` in the REPL to get a basic development server running. You can run `(repl/go)` at any point to restart this server. 28 | 29 | 30 | -------------------------------------------------------------------------------- /build-all.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | 5 | rm -rf packages/shadow-cljs/cli/dist/* 6 | 7 | lein with-profiles +cljs run -m shadow.cljs.devtools.cli release cli ui build-report babel-worker -------------------------------------------------------------------------------- /build-cli.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | 5 | lein run -m shadow.cljs.devtools.cli release cli 6 | 7 | cd packages/shadow-cljs; npm install -------------------------------------------------------------------------------- /build-deps.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | 5 | # CI-only 6 | # installing deps so they can be cached 7 | 8 | lein with-profiles +cljs deps 9 | 10 | cd packages/shadow-cljs-jar; mkdir bin; lein uberjar -------------------------------------------------------------------------------- /doc/ssl.md: -------------------------------------------------------------------------------- 1 | # Notes on creating a self-signed ssl cert 2 | 3 | https://certsimple.com/blog/localhost-ssl-fix 4 | 5 | until you get a .p12 file, then 6 | 7 | ``` 8 | keytool -importkeystore -destkeystore keystore.jks -srcstoretype PKCS12 -srckeystore test-cert.p12 9 | ``` 10 | 11 | this is ok but requires a password which I don't want to have in the shadow-cljs config. 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /externs/browser.txt: -------------------------------------------------------------------------------- 1 | fromSimpleExterns -------------------------------------------------------------------------------- /externs/infer-externs.txt: -------------------------------------------------------------------------------- 1 | # untyped externs will be generated by this file 2 | # the filename must match the .txt 3 | 4 | # properties are just listed one per line 5 | propertyA 6 | propertyB 7 | 8 | # globals are prefixed by global: 9 | global:someGlobal -------------------------------------------------------------------------------- /externs/launcher-renderer.txt: -------------------------------------------------------------------------------- 1 | # the build uses require and doesn't process the JS 2 | # so these props get renamed in fulcro since its not typehinted 3 | props 4 | state 5 | displayName -------------------------------------------------------------------------------- /externs/ui.txt: -------------------------------------------------------------------------------- 1 | # bundle_renderer.js is JS and can't use infer-externs 2 | on 3 | dx 4 | dy 5 | 6 | -------------------------------------------------------------------------------- /karma.conf.js: -------------------------------------------------------------------------------- 1 | module.exports = function(config) { 2 | config.set({ 3 | browsers: ['ChromeHeadless'], 4 | basePath: 'out/demo-karma', 5 | files: ['test.js'], 6 | frameworks: ['cljs-test'], 7 | plugins: ['karma-cljs-test', 'karma-chrome-launcher'], 8 | colors: true, 9 | logLevel: config.LOG_INFO, 10 | // FIXME: do we need this? 11 | client: {args: ["shadow.test.karma.init"], 12 | singleRun: true} 13 | }) 14 | }; 15 | -------------------------------------------------------------------------------- /npm-run.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | console.log("process-pid", process.pid); 4 | 5 | var lib = require("./packages/shadow-cljs/cli/dist.js"); 6 | lib.main(process.argv.slice(2)); 7 | 8 | -------------------------------------------------------------------------------- /out/azure-fn/.gitignore: -------------------------------------------------------------------------------- 1 | bin 2 | obj 3 | csx 4 | .vs 5 | edge 6 | Publish 7 | 8 | *.user 9 | *.suo 10 | *.cscfg 11 | *.Cache 12 | project.lock.json 13 | 14 | /packages 15 | /TestResults 16 | 17 | /tools/NuGet.exe 18 | /App_Data 19 | /secrets 20 | /data 21 | .secrets 22 | appsettings.json 23 | local.settings.json 24 | 25 | *.js 26 | 27 | node_modules 28 | -------------------------------------------------------------------------------- /out/azure-fn/.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": [ 3 | "ms-azuretools.vscode-azurefunctions" 4 | ] 5 | } -------------------------------------------------------------------------------- /out/azure-fn/host.json: -------------------------------------------------------------------------------- 1 | { } -------------------------------------------------------------------------------- /out/azure-fn/simple/function.json: -------------------------------------------------------------------------------- 1 | {"disabled":false,"bindings":[{"authLevel":"function","type":"httpTrigger","direction":"in","name":"req"},{"type":"http","direction":"out","name":"$return"}]} -------------------------------------------------------------------------------- /out/chrome-ext/.gitignore: -------------------------------------------------------------------------------- 1 | out/ 2 | manifest.json 3 | -------------------------------------------------------------------------------- /out/chrome-ext/browser-action.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | hello world!!! 8 | 9 | -------------------------------------------------------------------------------- /out/chrome-ext/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thheller/shadow-cljs/efd77b59a1f89a6c877e8471c26f127095271ec5/out/chrome-ext/icon.png -------------------------------------------------------------------------------- /out/chrome-manifest.edn: -------------------------------------------------------------------------------- 1 | {:name "Getting Started Example" 2 | :version "1.0" 3 | :description "Build an Extension!" 4 | :manifest-version 2 5 | 6 | :shadow/outputs 7 | {:inject 8 | {:output-type :chrome/single-file 9 | :init-fn demo.chrome.manual-inject/init} 10 | 11 | :browser-action 12 | {:init-fn demo.chrome.browser-action/init} 13 | 14 | :content-script 15 | {:init-fn demo.chrome.content/init 16 | :chrome/options {:matches ["http://localhost:*/*"] 17 | :run-at "document_idle"}} 18 | 19 | :background 20 | {:init-fn demo.chrome.bg/init}} 21 | 22 | ;; disable as only one of :page-action or :browser-action is allowed 23 | #_#_:page-action 24 | {:default-title "hello world" 25 | :default-icon "icon.png" 26 | :default-popup "page-action.html"} 27 | 28 | :browser-action 29 | {:default-title "hello world" 30 | :default-icon "icon.png" 31 | :default-popup "browser-action.html"} 32 | 33 | :content-security-policy 34 | ["default-src 'self';" 35 | ;; FIXME: unsafe-eval should be injected for dev, user shouldn't have to write this 36 | "script-src 'self' 'unsafe-eval' http://localhost:9630;" 37 | "connect-src * data: blob: filesystem:;" 38 | "style-src 'self' data: chrome-extension-resource: 'unsafe-inline';" 39 | "img-src 'self' data: chrome-extension-resource:;" 40 | "frame-src 'self' data: chrome-extension-resource:;" 41 | "font-src 'self' data: chrome-extension-resource:;" 42 | "media-src * data: blob: filesystem:;"]} 43 | 44 | -------------------------------------------------------------------------------- /out/cljs-tests/.gitignore: -------------------------------------------------------------------------------- 1 | *.js 2 | -------------------------------------------------------------------------------- /out/demo-bootstrap/.gitignore: -------------------------------------------------------------------------------- 1 | bootstrap/ 2 | script.js 3 | -------------------------------------------------------------------------------- /out/demo-browser/.gitignore: -------------------------------------------------------------------------------- 1 | public/js 2 | public/esm-js 3 | public/esm-js-auto 4 | -------------------------------------------------------------------------------- /out/demo-browser/index.src.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 |

hello world

7 | 8 |
9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /out/demo-browser/public/.gitignore: -------------------------------------------------------------------------------- 1 | /index.html -------------------------------------------------------------------------------- /out/demo-browser/public/css/foo.css: -------------------------------------------------------------------------------- 1 | body { 2 | color: green; 3 | } -------------------------------------------------------------------------------- /out/demo-browser/public/esm-auto.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /out/demo-browser/public/esm.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /out/demo-browser/public/ext.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 |

hello world

7 | 8 |
9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /out/demo-browser/public/foo/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | foo index 6 | 7 | 8 | asked for foo, got foo 9 | 10 | -------------------------------------------------------------------------------- /out/demo-browser/public/ws.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /out/demo-closure-es6/public/index.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /out/demo-closure/public/index.html: -------------------------------------------------------------------------------- 1 |

Hello World

2 |
3 | 4 | 5 | -------------------------------------------------------------------------------- /out/demo-foreign/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |

hello world

5 | 6 | 7 | 14 | -------------------------------------------------------------------------------- /out/demo-graal/.gitignore: -------------------------------------------------------------------------------- 1 | lib.js -------------------------------------------------------------------------------- /out/demo-karma/.gitignore: -------------------------------------------------------------------------------- 1 | test.js 2 | test.js.map 3 | -------------------------------------------------------------------------------- /out/demo-library/.gitignore: -------------------------------------------------------------------------------- 1 | lib.js 2 | -------------------------------------------------------------------------------- /out/demo-library/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "demo-library", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "lib.js", 6 | "dependencies": { 7 | "which": "^4.0.0" 8 | }, 9 | "scripts": { 10 | "test": "echo \"Error: no test specified\" && exit 1" 11 | }, 12 | "keywords": [], 13 | "author": "", 14 | "license": "ISC" 15 | } 16 | -------------------------------------------------------------------------------- /out/demo-library/script.js: -------------------------------------------------------------------------------- 1 | require("source-map-support").install(); 2 | 3 | var x = require("./lib"); 4 | console.log("x", x); 5 | var result = x.hello(); 6 | console.log("hello result", result); 7 | -------------------------------------------------------------------------------- /out/demo-now/.gitignore: -------------------------------------------------------------------------------- 1 | index.js 2 | -------------------------------------------------------------------------------- /out/demo-now/now.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": 2, 3 | "builds": [ 4 | { "src": "index.js", 5 | "use": "@now/node" 6 | } 7 | ], 8 | "routes":[ 9 | { 10 | "src":"/(.*)", 11 | "dest":"/index.js" 12 | } 13 | ] 14 | } -------------------------------------------------------------------------------- /out/demo-now/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "demo-now", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC" 12 | } 13 | -------------------------------------------------------------------------------- /out/demo-npm/.gitignore: -------------------------------------------------------------------------------- 1 | lib/ 2 | -------------------------------------------------------------------------------- /out/demo-npm/script.js: -------------------------------------------------------------------------------- 1 | var x = require("./lib/demo.npm") 2 | 3 | console.log(x.foo()); 4 | -------------------------------------------------------------------------------- /out/demo-script-bundle/.gitignore: -------------------------------------------------------------------------------- 1 | script.js 2 | -------------------------------------------------------------------------------- /out/demo-script/.gitignore: -------------------------------------------------------------------------------- 1 | script.js 2 | -------------------------------------------------------------------------------- /out/demo-script/foo.js: -------------------------------------------------------------------------------- 1 | console.log("foo"); 2 | -------------------------------------------------------------------------------- /out/demo-script/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "demo-script", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "foo.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC", 12 | "dependencies": { 13 | "react": "^18.2.0", 14 | "request": "^2.88.2", 15 | "which": "^3.0.0" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /out/demo-selfhost/.gitignore: -------------------------------------------------------------------------------- 1 | public/bootstrap 2 | -------------------------------------------------------------------------------- /out/demo-selfhost/public/index-worker.html: -------------------------------------------------------------------------------- 1 |
2 |

 3 | 
4 |
5 | 6 | 7 |
8 |
9 | ANIMATION 10 |
11 |
12 | 13 | 42 | 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /out/demo-selfhost/public/index.html: -------------------------------------------------------------------------------- 1 |
2 |

 3 | 
4 |
5 | 6 | 7 |
8 |
9 | ANIMATION 10 |
11 |
12 | 13 | 42 | 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /out/demo-single/.gitignore: -------------------------------------------------------------------------------- 1 | lib.js 2 | lib.js.map 3 | -------------------------------------------------------------------------------- /out/demo-sm-test/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /out/demo-test-browser/index.html: -------------------------------------------------------------------------------- 1 | 2 | shadow.test.browser -------------------------------------------------------------------------------- /out/demo-test-dummy/index.html: -------------------------------------------------------------------------------- 1 | 2 | shadow.test.browser



--------------------------------------------------------------------------------
/out/demo-test-node-fail/.gitignore:
--------------------------------------------------------------------------------
1 | *.js
2 | 


--------------------------------------------------------------------------------
/out/demo-test-node/.gitignore:
--------------------------------------------------------------------------------
1 | script.js
2 | 


--------------------------------------------------------------------------------
/out/demo-warnings/.gitignore:
--------------------------------------------------------------------------------
1 | *.js
2 | 


--------------------------------------------------------------------------------
/out/esm-node/.gitignore:
--------------------------------------------------------------------------------
1 | js/
2 | 


--------------------------------------------------------------------------------
/out/esm-node/package.json:
--------------------------------------------------------------------------------
 1 | {
 2 |   "name": "esm-node",
 3 |   "version": "1.0.0",
 4 |   "description": "",
 5 |   "type": "module",
 6 |   "main": "index.js",
 7 |   "scripts": {
 8 |     "test": "echo \"Error: no test specified\" && exit 1"
 9 |   },
10 |   "keywords": [],
11 |   "author": "",
12 |   "license": "ISC",
13 |   "dependencies": {
14 |     "ink": "^4.2.0"
15 |   }
16 | }
17 | 


--------------------------------------------------------------------------------
/out/node-repl-dev/.gitignore:
--------------------------------------------------------------------------------
1 | node-repl.js
2 | 
3 | 


--------------------------------------------------------------------------------
/out/npm-web/.gitignore:
--------------------------------------------------------------------------------
1 | src/cljs/
2 | dist/
3 | 


--------------------------------------------------------------------------------
/out/npm-web/index.html:
--------------------------------------------------------------------------------
 1 | 
 2 | 
 3 | 
 4 | 
 5 | 
 6 | 
 7 | 
8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /out/npm-web/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "npm-web", 3 | "version": "1.0.0", 4 | "license": "MIT", 5 | "dependencies": { 6 | "react": "^18.2.0", 7 | "react-dom": "^18.2.0", 8 | "webpack": "^5.88.2", 9 | "webpack-cli": "^5.1.4" 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /out/npm-web/src/index.js: -------------------------------------------------------------------------------- 1 | if (process.env.NODE_ENV !== "production") { 2 | window["$CLJS"] = require("./cljs/cljs_env"); 3 | require("./cljs/shadow.cljs.devtools.client.browser"); 4 | } 5 | 6 | var x = require("./cljs/demo.repl"); 7 | console.log(x); 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /out/npm-web/webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require("path"); 2 | 3 | module.exports = { 4 | entry: "./src/index.js", 5 | 6 | output: { 7 | path: path.resolve(__dirname, "dist"), 8 | filename: "bundle.js" 9 | } 10 | }; 11 | -------------------------------------------------------------------------------- /out/webpack-bundle/.gitignore: -------------------------------------------------------------------------------- 1 | public/js/ 2 | -------------------------------------------------------------------------------- /out/webpack-bundle/public/index.html: -------------------------------------------------------------------------------- 1 |

hello world

2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /out/webpack-dll/.gitignore: -------------------------------------------------------------------------------- 1 | js/ 2 | -------------------------------------------------------------------------------- /out/webpack-dll/a.js: -------------------------------------------------------------------------------- 1 | if (window["shadow$webpack"] === undefined) { 2 | window["shadow$webpack"] = {}; 3 | 4 | window["require"] = function(name) { 5 | return window["shadow$webpack"][name]; 6 | }; 7 | } 8 | window["shadow$webpack"]["react"] = require("react"); -------------------------------------------------------------------------------- /out/webpack-dll/b.js: -------------------------------------------------------------------------------- 1 | if (window["shadow$webpack"] === undefined) { 2 | window["shadow$webpack"] = {}; 3 | } 4 | window["shadow$webpack"]["react-dom"] = require("react-dom"); -------------------------------------------------------------------------------- /out/webpack-dll/dll-a.config.js: -------------------------------------------------------------------------------- 1 | var path = require("path"); 2 | var webpack = require("webpack"); 3 | 4 | module.exports = { 5 | entry: ["./a"], 6 | output: { 7 | path: path.join(__dirname, "js"), 8 | filename: "a.js", 9 | library: "shadow$dll_a" 10 | }, 11 | plugins: [ 12 | new webpack.DllPlugin({ 13 | path: path.join(__dirname, "js", "a-manifest.json"), 14 | name: "shadow$dll_a" 15 | }) 16 | ] 17 | }; -------------------------------------------------------------------------------- /out/webpack-dll/dll-b.config.js: -------------------------------------------------------------------------------- 1 | var path = require("path"); 2 | var webpack = require("webpack"); 3 | 4 | module.exports = { 5 | entry: { 6 | b: ["./b"] 7 | }, 8 | output: { 9 | path: path.join(__dirname, "js"), 10 | filename: "[name].js", 11 | library: "shadow$dll_[name]" 12 | }, 13 | plugins: [ 14 | // new webpack.NamedModulesPlugin(), 15 | new webpack.DllReferencePlugin({ manifest: require("./js/a-manifest.json") }), 16 | new webpack.DllPlugin({ 17 | path: path.join(__dirname, "js", "[name]-manifest.json"), 18 | name: "shadow$dll_[name]" 19 | }) 20 | ] 21 | }; -------------------------------------------------------------------------------- /out/webpack-dll/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "scripts": {}, 4 | "dependencies": { 5 | "jsdom": "^24.0.0", 6 | "readline-sync": "^1.4.10", 7 | "source-map-support": "^0.5.21", 8 | "ws": "^7.5.8" 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /packages/.gitignore: -------------------------------------------------------------------------------- 1 | local-testing/ 2 | -------------------------------------------------------------------------------- /packages/babel-worker/.gitignore: -------------------------------------------------------------------------------- 1 | /out 2 | /dist 3 | -------------------------------------------------------------------------------- /packages/babel-worker/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "babel-worker", 3 | "version": "1.0.0", 4 | "private": true, 5 | "description": "", 6 | "main": "index.js", 7 | "scripts": { 8 | "build": "ncc build out/babel-worker.js -o dist && cp dist/index.js ../../src/ui-release/shadow/cljs/dist/babel-worker.js" 9 | }, 10 | "keywords": [], 11 | "author": "", 12 | "license": "ISC", 13 | "dependencies": { 14 | "@babel/core": "7.15.5", 15 | "@babel/preset-env": "7.10.2", 16 | "@vercel/ncc": "0.36.1" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /packages/chrome-ext/.gitignore: -------------------------------------------------------------------------------- 1 | manifest.json 2 | out/ -------------------------------------------------------------------------------- /packages/chrome-ext/chrome-manifest.edn: -------------------------------------------------------------------------------- 1 | {:name "shadow-cljs devtools" 2 | :version "1.0" 3 | :description "Accesses shadow-cljs UI in the Chrome Devtools" 4 | :manifest-version 2 5 | 6 | :devtools-page "shadow-cljs.html" 7 | 8 | :content-security-policy 9 | ["default-src 'self';" 10 | ;; FIXME: unsafe-eval should be injected for dev, user shouldn't have to write this 11 | "script-src 'self' 'unsafe-eval' http://localhost:9630;" 12 | "connect-src * data: blob: filesystem:;" 13 | "style-src 'self' data: chrome-extension-resource: 'unsafe-inline';" 14 | "img-src 'self' data: chrome-extension-resource:;" 15 | ;; FIXME: localhost only? don't want to allow any origin though 16 | "frame-src 'self' http://localhost:* data: chrome-extension-resource:;" 17 | "font-src 'self' data: chrome-extension-resource:;" 18 | "media-src * data: blob: filesystem:;"]} 19 | 20 | -------------------------------------------------------------------------------- /packages/chrome-ext/panel.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | shadow-cljs panel 6 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /packages/chrome-ext/shadow-cljs.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | shadow-cljs 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /packages/create-cljs-project/.gitignore: -------------------------------------------------------------------------------- 1 | dist/ 2 | -------------------------------------------------------------------------------- /packages/create-cljs-project/.npmignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thheller/shadow-cljs/efd77b59a1f89a6c877e8471c26f127095271ec5/packages/create-cljs-project/.npmignore -------------------------------------------------------------------------------- /packages/create-cljs-project/files/gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | public/js 3 | 4 | /target 5 | /checkouts 6 | /src/gen 7 | 8 | pom.xml 9 | pom.xml.asc 10 | *.iml 11 | *.jar 12 | *.log 13 | .shadow-cljs 14 | .idea 15 | .lein-* 16 | .nrepl-* 17 | .DS_Store 18 | 19 | .hgignore 20 | .hg/ 21 | -------------------------------------------------------------------------------- /packages/create-cljs-project/files/shadow-cljs.edn: -------------------------------------------------------------------------------- 1 | ;; shadow-cljs configuration 2 | {:source-paths 3 | ["src/dev" 4 | "src/main" 5 | "src/test"] 6 | 7 | :dependencies 8 | [] 9 | 10 | :builds 11 | {}} 12 | -------------------------------------------------------------------------------- /packages/create-cljs-project/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "create-cljs-project", 3 | "author": { 4 | "name": "Thomas Heller" 5 | }, 6 | "bin": { 7 | "create-cljs-project": "./dist/script.js" 8 | }, 9 | "dependencies": { 10 | }, 11 | "description": "", 12 | "keywords": [ 13 | "clojurescript", 14 | "cljs", 15 | "shadow-cljs" 16 | ], 17 | "license": "ISC", 18 | "main": "./dist/script.js", 19 | "version": "0.0.15" 20 | } 21 | -------------------------------------------------------------------------------- /packages/external-testing/.gitignore: -------------------------------------------------------------------------------- 1 | dist/ 2 | index.js 3 | -------------------------------------------------------------------------------- /packages/external-testing/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "external-testing", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "build": "webpack --mode production ./index.js -o ../../out/demo-browser/public/js/ext" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC", 12 | "devDependencies": { 13 | "webpack": "^5.76.2", 14 | "webpack-cli": "^5.0.1" 15 | }, 16 | "dependencies": { 17 | "antd": "^5.3.2", 18 | "react": "^18.2.0" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /packages/resolve-check/.gitignore: -------------------------------------------------------------------------------- 1 | /run.js 2 | -------------------------------------------------------------------------------- /packages/resolve-check/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "resolve-check", 3 | "private": true, 4 | "version": "1.0.0", 5 | "description": "", 6 | "main": "index.js", 7 | "scripts": { 8 | "test": "echo \"Error: no test specified\" && exit 1" 9 | }, 10 | "keywords": [], 11 | "author": "", 12 | "license": "ISC", 13 | "dependencies": { 14 | "enhanced-resolve": "^5.8.3", 15 | "source-map-support": "^0.5.21" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /packages/resolve-check/test.js: -------------------------------------------------------------------------------- 1 | const fs = require("fs"); 2 | const path = require("path"); 3 | 4 | const { CachedInputFileSystem, ResolverFactory } = require("enhanced-resolve"); 5 | 6 | // create a resolver 7 | const myResolver = ResolverFactory.createResolver({ 8 | // Typical usage will consume the `fs` + `CachedInputFileSystem`, which wraps Node.js `fs` to add caching. 9 | fileSystem: new CachedInputFileSystem(fs, 4000), 10 | extensions: [".js", ".json"], 11 | aliasFields: ["browser"] 12 | /* any other resolver options here. Options/defaults can be seen below */ 13 | }); 14 | 15 | // resolve a file with the new resolver 16 | const context = {}; 17 | const resolveContext = { 18 | log: function(msg) { 19 | console.log("resolve-context: ", msg) 20 | } 21 | }; 22 | const lookupStartPath = path.resolve("..", "..", "test-env"); 23 | const request = "browser-override/web"; 24 | 25 | myResolver.resolve({}, lookupStartPath, request, resolveContext, ( 26 | err /*Error*/, 27 | filepath /*string*/ 28 | ) => { 29 | console.log("err", err); 30 | console.log("path", filepath); 31 | }); 32 | 33 | -------------------------------------------------------------------------------- /packages/shadow-cljs-jar/.gitignore: -------------------------------------------------------------------------------- 1 | target 2 | -------------------------------------------------------------------------------- /packages/shadow-cljs-jar/.npmignore: -------------------------------------------------------------------------------- 1 | target 2 | src 3 | project.clj 4 | *.iml 5 | *.tgz 6 | -------------------------------------------------------------------------------- /packages/shadow-cljs-jar/README.md: -------------------------------------------------------------------------------- 1 | This is a utility used by `shadow-cljs` to resolve/download dependencies. 2 | 3 | https://github.com/thheller/shadow-cljs 4 | -------------------------------------------------------------------------------- /packages/shadow-cljs-jar/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "shadow-cljs-jar", 3 | "version": "1.3.4", 4 | "description": "shadow-cljs dependency resolver/downloader", 5 | "author": "Thomas Heller", 6 | "license": "ISC", 7 | "bugs": { 8 | "url": "https://github.com/thheller/shadow-cljs/issues" 9 | }, 10 | "homepage": "https://github.com/thheller/shadow-cljs#readme", 11 | "repository": { 12 | "type": "git", 13 | "url": "git+https://github.com/thheller/shadow-cljs.git" 14 | }, 15 | "keywords": [ 16 | "clojurescript", 17 | "cljs" 18 | ], 19 | "scripts":{ 20 | "prepublish":"lein uberjar" 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /packages/shadow-cljs-jar/path.js: -------------------------------------------------------------------------------- 1 | var path = require("path"); 2 | module.exports = path.resolve(__dirname, "bin", "shadow-cljs.jar"); 3 | -------------------------------------------------------------------------------- /packages/shadow-cljs-jar/project.clj: -------------------------------------------------------------------------------- 1 | (defproject shadow-cljs-jar "1.3.4" 2 | 3 | :javac-options 4 | ["-target" "1.8" 5 | "-source" "1.8"] 6 | 7 | :dependencies 8 | [[org.clojure/clojure "1.10.1"] 9 | [com.cemerick/pomegranate "1.1.0"] 10 | [org.slf4j/slf4j-nop "1.7.30"] 11 | [s3-wagon-private "1.3.5" 12 | :exclusions 13 | [ch.qos.logback/logback-classic]]] 14 | 15 | ;; uses target/ as the root not PWD 16 | :uberjar-name "../bin/shadow-cljs.jar" 17 | 18 | :aot :all 19 | :main shadow.cljs.npm.deps) 20 | -------------------------------------------------------------------------------- /packages/shadow-cljs-jar/test.edn: -------------------------------------------------------------------------------- 1 | {:dependencies 2 | [[thheller/shadow-cljs "2.7.24"]]} 3 | 4 | -------------------------------------------------------------------------------- /packages/shadow-cljs/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "ignore": ["*.js"] 3 | } 4 | 5 | -------------------------------------------------------------------------------- /packages/shadow-cljs/.gitignore: -------------------------------------------------------------------------------- 1 | cli/dist.js 2 | node_modules 3 | -------------------------------------------------------------------------------- /packages/shadow-cljs/.npmignore: -------------------------------------------------------------------------------- 1 | *.tgz 2 | -------------------------------------------------------------------------------- /packages/shadow-cljs/README.md: -------------------------------------------------------------------------------- 1 | See: https://github.com/thheller/shadow-cljs 2 | -------------------------------------------------------------------------------- /packages/shadow-cljs/cli/default-config.edn: -------------------------------------------------------------------------------- 1 | ;; shadow-cljs configuration 2 | {:source-paths 3 | ["src/dev" 4 | "src/main" 5 | "src/test"] 6 | 7 | :dependencies 8 | [] 9 | 10 | :builds 11 | {}} 12 | -------------------------------------------------------------------------------- /packages/shadow-cljs/cli/runner.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | // this script searches for a local install of shadow-cljs 4 | // so it uses the version installed in the project over a globally installed version 5 | // but the global still works standalone if no package.json exists 6 | // so CLJS-only projects don't have to have a package.json present 7 | // but can still use the CLI script 8 | 9 | var fs = require("fs"); 10 | var path = require("path"); 11 | 12 | var localLib = null; 13 | 14 | var root = process.cwd(); 15 | 16 | // replicate default node resolve which looks in parent directories as well 17 | // so you can run it from $PROJECT/src/foo and have it pick up $PROJECT/node_modules 18 | for (;;) { 19 | var test = path.resolve(root, "node_modules", "shadow-cljs", "cli", "dist.js") 20 | 21 | if (fs.existsSync(test)) { 22 | localLib = test; 23 | break; 24 | } 25 | 26 | var nextRoot = path.resolve(root, ".."); 27 | if (nextRoot == root) { 28 | break; 29 | } else { 30 | root = nextRoot; 31 | } 32 | } 33 | 34 | var lib = null; 35 | if (localLib != null) { 36 | // console.log("shadow-cljs - using project version"); 37 | lib = require(localLib); 38 | } else { 39 | // console.log("shadow-cljs - using global version") 40 | 41 | // this throws if not found right? 42 | lib = require("./dist.js"); 43 | } 44 | 45 | if (lib == null) { 46 | console.log("failed to require CLI lib", localLib); 47 | } else { 48 | lib.main(process.argv.slice(2)); 49 | } 50 | 51 | -------------------------------------------------------------------------------- /packages/shadow-cljs/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "shadow-cljs", 3 | "version": "3.1.5", 4 | "jar-version": "3.1.5", 5 | "description": "ClojureScript compiler and JS bundler", 6 | "author": "Thomas Heller", 7 | "license": "ISC", 8 | "bugs": { 9 | "url": "https://github.com/thheller/shadow-cljs/issues" 10 | }, 11 | "homepage": "https://github.com/thheller/shadow-cljs#readme", 12 | "repository": { 13 | "type": "git", 14 | "url": "git+https://github.com/thheller/shadow-cljs.git" 15 | }, 16 | "keywords": [ 17 | "clojurescript", 18 | "cljs" 19 | ], 20 | "bin": { 21 | "shadow-cljs": "./cli/runner.js" 22 | }, 23 | "engines": { 24 | "node": ">=6.0.0" 25 | }, 26 | "dependencies": { 27 | "buffer": "^6.0.3", 28 | "process": "^0.11.10", 29 | "readline-sync": "^1.4.10", 30 | "shadow-cljs-jar": "1.3.4", 31 | "source-map-support": "^0.5.21", 32 | "which": "^5.0.0", 33 | "ws": "^8.18.1" 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /packages/testing/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "testing", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC", 12 | "dependencies": { 13 | "node-libs-browser": "^2.2.1", 14 | "react": "^17.0.2", 15 | "react-dom": "^17.0.2" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /packages/ui/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "shadow-cljs-ui-packages", 3 | "private": true, 4 | "dependencies": { 5 | "codemirror": "^5.37.0", 6 | "parinfer-codemirror": "^1.4.2", 7 | "react": "^16.0.0", 8 | "react-dom": "^16.0.0", 9 | "react-table": "^6.8.2", 10 | "react-virtualized-auto-sizer": "^1.0.2", 11 | "react-window": "^1.8.5", 12 | "xterm": "3.10.1" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | tailwindcss: {}, 4 | autoprefixer: {}, 5 | cssnano: process.env.NODE_ENV == 'production' ? {} : false 6 | } 7 | } -------------------------------------------------------------------------------- /src/dev/build.clj: -------------------------------------------------------------------------------- 1 | (ns build 2 | (:require 3 | [shadow.css.build :as cb] 4 | [clojure.java.io :as io])) 5 | 6 | (defn css-release [] 7 | (let [build-state 8 | (-> (cb/start) 9 | (cb/index-path (io/file "src" "main") {}) 10 | (cb/generate 11 | '{:ui 12 | {:entries [shadow.cljs.ui.main 13 | ;; FIXME: since this is lazy-loaded shadow.css doesn't find it on its own 14 | shadow.cljs.ui.components.code-editor]}}) 15 | (cb/minify) 16 | (cb/write-outputs-to (io/file "src" "ui-release" "shadow" "cljs" "ui" "dist" "css")))] 17 | 18 | (doseq [mod (:outputs build-state) 19 | {:keys [warning-type] :as warning} (:warnings mod)] 20 | 21 | (prn [:CSS (name warning-type) (dissoc warning :warning-type)])) 22 | )) 23 | 24 | (comment 25 | (time 26 | (css-release))) -------------------------------------------------------------------------------- /src/dev/data_readers.cljc: -------------------------------------------------------------------------------- 1 | {foo demo.browser/read-foo} -------------------------------------------------------------------------------- /src/dev/demo/always_load.cljs: -------------------------------------------------------------------------------- 1 | (ns ^:dev/always demo.always-load) 2 | 3 | (js/console.log "hello from always reload") 4 | -------------------------------------------------------------------------------- /src/dev/demo/azure/simple.cljs: -------------------------------------------------------------------------------- 1 | (ns demo.azure.simple 2 | (:require ["react-dom/server" :as rdom])) 3 | 4 | (defn test-fn 5 | {:azure/disabled false 6 | :azure/bindings 7 | [{:authLevel "function" 8 | :type "httpTrigger" 9 | :direction "in" 10 | :name "req"} 11 | {:type "http" 12 | :direction "out" 13 | :name "$return"}]} 14 | [^js context ^js req] 15 | (.. context (log "JavaScript HTTP trigger function processed a request.")) 16 | 17 | (let [name (or (.. req -query -name) 18 | (and (.. req -body) (.. req -body -name))) 19 | 20 | result 21 | (if (seq name) 22 | {:status 200 23 | :body (str "CLJS: Hello " name)} 24 | {:status 400 25 | :body "Please pass a name on the query string or in the request body"})] 26 | 27 | (.. context (done nil (clj->js result))))) 28 | -------------------------------------------------------------------------------- /src/dev/demo/bootstrap_script.cljs: -------------------------------------------------------------------------------- 1 | (ns demo.bootstrap-script 2 | (:require 3 | [cljs.js :as cljs] 4 | [cljs.env :as env] 5 | [shadow.cljs.bootstrap.node :as boot])) 6 | 7 | (defn print-result [{:keys [error value] :as result}] 8 | (prn [:result result])) 9 | 10 | (def code "(prn ::foo) (+ 1 2)") 11 | 12 | (defonce compile-state-ref (env/default-compiler-env)) 13 | 14 | (defn compile-it [] 15 | (cljs/eval-str 16 | compile-state-ref 17 | code 18 | "[test]" 19 | {:eval cljs/js-eval 20 | :load (partial boot/load compile-state-ref)} 21 | print-result)) 22 | 23 | (defn main [& args] 24 | (boot/init compile-state-ref {} compile-it)) 25 | -------------------------------------------------------------------------------- /src/dev/demo/browser-externs.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @externs 3 | */ 4 | 5 | /** 6 | * @constructor 7 | */ 8 | var Foreign = function() {}; 9 | 10 | Foreign.prototype.createElement; 11 | Foreign.prototype.render; 12 | 13 | Foreign.prototype.Component; -------------------------------------------------------------------------------- /src/dev/demo/browser.clj: -------------------------------------------------------------------------------- 1 | (ns demo.browser) 2 | 3 | (defmacro test-macro [a b c] 4 | ;;(throw (ex-info "macro bad" {})) 5 | (meta *ns*)) 6 | 7 | (defmacro bad-macro [& args] 8 | (throw (ex-info "bad-macro is bad" {}))) 9 | 10 | (defn read-foo [x] 11 | [::foo x]) -------------------------------------------------------------------------------- /src/dev/demo/browser_extra.cljs: -------------------------------------------------------------------------------- 1 | (ns demo.browser-extra 2 | (:require [demo.browser :as b])) 3 | 4 | (js/console.log "bar") 5 | (js/console.log "demo.browser-extra" ::foo ::foo) 6 | 7 | ;; (throw (ex-info "boom!" {})) 8 | 9 | (def x "i'm from browser-extra") 10 | (def y "i'm from browser-extra too") -------------------------------------------------------------------------------- /src/dev/demo/browser_specs.cljs: -------------------------------------------------------------------------------- 1 | (ns demo.browser-specs) 2 | 3 | (js/console.log "hello I was auto-included?!") 4 | -------------------------------------------------------------------------------- /src/dev/demo/cant_compile.cljs: -------------------------------------------------------------------------------- 1 | (ns demo.cant-compile) 2 | 3 | ;; (foo 4 | -------------------------------------------------------------------------------- /src/dev/demo/chrome/bg.cljs: -------------------------------------------------------------------------------- 1 | (ns demo.chrome.bg) 2 | 3 | (defn init [] 4 | (js/console.log "chrome-bg") 5 | 6 | (js/console.log "▶❤◀") 7 | 8 | (js/chrome.runtime.onInstalled.addListener 9 | (fn [] 10 | (js/console.log "Installed!") 11 | ))) -------------------------------------------------------------------------------- /src/dev/demo/chrome/browser_action.cljs: -------------------------------------------------------------------------------- 1 | (ns demo.chrome.browser-action 2 | (:require ["react" :as react])) 3 | 4 | (js/console.log "yo!") 5 | 6 | (defn init [] 7 | (js/console.warn "browser-action" react) 8 | 9 | (-> (js/chrome.extension.getBackgroundPage) 10 | (.-console) 11 | (.warn "browser-action" react))) 12 | -------------------------------------------------------------------------------- /src/dev/demo/chrome/content.cljs: -------------------------------------------------------------------------------- 1 | (ns demo.chrome.content) 2 | 3 | (js/console.warn "ALL YOUR PAGE ARE BELONG TO US!!!") 4 | 5 | (defn init [] 6 | (js/console.log "▶❤◀")) 7 | 8 | (defn ^:dev/after-load call-me-maybe [] 9 | (js/console.warn "actually called!")) -------------------------------------------------------------------------------- /src/dev/demo/chrome/manual_inject.cljs: -------------------------------------------------------------------------------- 1 | (ns demo.chrome.manual-inject) 2 | 3 | (defn init [] 4 | (js/console.log "manual-inject!")) 5 | -------------------------------------------------------------------------------- /src/dev/demo/chrome/page_action.cljs: -------------------------------------------------------------------------------- 1 | (ns demo.chrome.page-action) 2 | 3 | (js/console.warn "page-action") 4 | -------------------------------------------------------------------------------- /src/dev/demo/cjs.js: -------------------------------------------------------------------------------- 1 | 2 | var foo = "foo"; 3 | 4 | module.exports = { foo }; -------------------------------------------------------------------------------- /src/dev/demo/cljc.cljc: -------------------------------------------------------------------------------- 1 | (ns demo.cljc) 2 | -------------------------------------------------------------------------------- /src/dev/demo/closure.cljs: -------------------------------------------------------------------------------- 1 | (ns demo.closure 2 | (:require ["./es6" :as x :refer (foo) :default defaultExport])) 3 | 4 | (js/console.log "foo" (foo "foo")) 5 | (js/console.log "bar" (foo "bar")) 6 | (js/console.log defaultExport) 7 | -------------------------------------------------------------------------------- /src/dev/demo/dce.cljs: -------------------------------------------------------------------------------- 1 | (ns demo.dce 2 | (:require 3 | ["react" :as r] 4 | ["react-dom" :as rd])) 5 | 6 | (defn never-used [] 7 | (js/console.log "never-used" r) 8 | 1) 9 | 10 | ;; react-dom uses react so react should not be removed! 11 | ;; (js/console.log "react-dom" rd) 12 | ;; (js/console.log "react" r) 13 | 14 | (def x (atom 1)) 15 | 16 | (js/console.log "demo.dce") -------------------------------------------------------------------------------- /src/dev/demo/defn_error.clj: -------------------------------------------------------------------------------- 1 | (ns demo.defn-error) 2 | 3 | (defn x [] 4 | :foo) 5 | -------------------------------------------------------------------------------- /src/dev/demo/dev_setup.clj: -------------------------------------------------------------------------------- 1 | (ns demo.dev-setup 2 | (:require 3 | [clojure.core.async :as async :refer (go (async/sliding-buffer 10) 19 | (async/chan))] 20 | (go (loop [] 21 | (when-let [msg ( { 12 | console.log(`Printing ${x} from cljs!`); 13 | console.log(core.assoc(null, 1, 2)); 14 | return bar(x); 15 | }; 16 | 17 | async function someAsyncFn(thing) { 18 | var value = await thing; 19 | console.log("await value", value); 20 | } 21 | 22 | export class Thing { 23 | constructor() { 24 | console.log("hello world"); 25 | } 26 | } 27 | 28 | export { foo, someAsyncFn, a, rest }; 29 | export default "defaultExport"; -------------------------------------------------------------------------------- /src/dev/demo/esm/a.cljs: -------------------------------------------------------------------------------- 1 | (ns demo.esm.a 2 | (:require 3 | ["https://cdn.pika.dev/preact@^10.0.0" :as x])) 4 | 5 | (def ^:export foo (str :foo "demo.esm.a/foo")) 6 | 7 | (def bar "demo.esm.a/bar") 8 | 9 | (defn ^:dev/after-load init [] 10 | (js/console.log "init from esm.a" x foo)) 11 | 12 | 13 | (def ^:export default "demo.esm.a/default") -------------------------------------------------------------------------------- /src/dev/demo/esm/b.cljs: -------------------------------------------------------------------------------- 1 | (ns demo.esm.b 2 | (:require 3 | ["dummy" :as d])) 4 | 5 | (def ^:export bar (str :bar "demo.esm.b/bar")) 6 | 7 | (def ^:export default (d/foo "demo.esm.b/default")) 8 | 9 | -------------------------------------------------------------------------------- /src/dev/demo/esm/c.cljs: -------------------------------------------------------------------------------- 1 | (ns demo.esm.c 2 | (:require 3 | [demo.esm.b :as b] 4 | ["dummy" :as d])) 5 | 6 | (def ^:export foo (str b/bar "+demo.esm.c/foo")) 7 | 8 | (def ^:export bar (d/foo "c")) 9 | 10 | 11 | -------------------------------------------------------------------------------- /src/dev/demo/esm/node.cljs: -------------------------------------------------------------------------------- 1 | (ns demo.esm.node 2 | (:require ["ink" :as ink])) 3 | 4 | (defn init [] 5 | (js/console.log ink)) 6 | -------------------------------------------------------------------------------- /src/dev/demo/expo.cljs: -------------------------------------------------------------------------------- 1 | (ns demo.expo 2 | (:require 3 | ["react" :as react :rename {createElement $}] 4 | ["react-native" :as rn :refer (Button Text View)] 5 | [shadow.expo :as expo] 6 | )) 7 | 8 | (defn fail [] 9 | (throw (ex-info "failed" {}))) 10 | 11 | (defn render-root [] 12 | ($ View nil 13 | ($ Text nil "Hello World from CLJS! 1") 14 | ($ Text nil "Hello World from CLJS! 2") 15 | ($ Text nil "Hello World from CLJS! 3") 16 | ($ Button #js {:title "Hello World" :onPress fail}))) 17 | 18 | (defn ^:dev/after-load start [] 19 | (expo/render-root (render-root))) 20 | 21 | (defn init [] 22 | (start)) -------------------------------------------------------------------------------- /src/dev/demo/foo-bar.cljs: -------------------------------------------------------------------------------- 1 | (ns demo.foo-bar) 2 | 3 | ;; testing filename warning -------------------------------------------------------------------------------- /src/dev/demo/foo.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | console.log("react", require("react")); 4 | 5 | -------------------------------------------------------------------------------- /src/dev/demo/foreign-ext.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @constructor 3 | */ 4 | var Foreign = function() {}; 5 | 6 | Foreign.prototype.helloWorld = function() {}; 7 | -------------------------------------------------------------------------------- /src/dev/demo/foreign.cljs: -------------------------------------------------------------------------------- 1 | (ns demo.foreign) 2 | 3 | (defn ^:export foo [x] 4 | (.helloWorld x)) 5 | 6 | 7 | (defprotocol IBar 8 | (bar [x])) 9 | 10 | (defrecord Bar [x] 11 | IBar 12 | (bar [_] (str "Bar" x))) 13 | 14 | (defrecord Bar2 [x] 15 | IBar 16 | (bar [_] (str "Bar2" x))) 17 | 18 | (defn do-it [^not-native x] 19 | (str "do-it" (bar x))) 20 | 21 | (js/console.log (do-it (Bar. "x"))) 22 | (js/console.log (satisfies? IBar (Bar. "x"))) 23 | (js/console.log (implements? IBar (Bar. "x"))) 24 | 25 | (defn dest [{:keys [foo] :as opts}] 26 | foo) 27 | 28 | (js/console.log (dest {:foo "foo"})) 29 | 30 | -------------------------------------------------------------------------------- /src/dev/demo/fulcro_expo.cljs: -------------------------------------------------------------------------------- 1 | (ns demo.fulcro-expo 2 | (:require 3 | ["expo" :as ex] 4 | ["react-native" :as rn] 5 | ["react" :as r] 6 | [fulcro.client :as fc] 7 | [fulcro.client.primitives :as fp :refer (defsc)] 8 | [shadow.expo :as expo] 9 | )) 10 | 11 | (defonce root-ref (atom nil)) 12 | 13 | (defonce app-ref (atom nil)) 14 | 15 | (def styles 16 | ^js (-> {:container 17 | {:flex 1 18 | :backgroundColor "#fff" 19 | :alignItems "center" 20 | :justifyContent "center"} 21 | :title 22 | {:fontWeight "bold" 23 | :fontSize 24 24 | :color "blue"}} 25 | (clj->js) 26 | (rn/StyleSheet.create))) 27 | 28 | (defsc Root [this props] 29 | {:initial-state 30 | (fn [p] 31 | {::foo "hello world"}) 32 | 33 | :query 34 | [::foo]} 35 | 36 | (r/createElement rn/View #js {:style (.-container styles)} 37 | (r/createElement rn/Text #js {:style (.-title styles)} "Hello!") 38 | (r/createElement rn/Text nil (pr-str props)))) 39 | 40 | (defn start 41 | {:dev/after-load true} 42 | [] 43 | (reset! app-ref (fc/mount @app-ref Root :i-got-no-dom-node))) 44 | 45 | (defn init [] 46 | (let [app 47 | (fc/make-fulcro-client 48 | {:client-did-mount 49 | (fn [{:keys [reconciler] :as app}]) 50 | 51 | :reconciler-options 52 | {:root-render expo/render-root 53 | :root-unmount (fn [node])}})] 54 | 55 | (reset! app-ref app) 56 | (start))) 57 | 58 | -------------------------------------------------------------------------------- /src/dev/demo/graal.cljs: -------------------------------------------------------------------------------- 1 | (ns demo.graal) 2 | 3 | (defn ^:export hello [foo] 4 | (str "Hello, " foo "!") 5 | (assoc [] 3 "foo")) 6 | -------------------------------------------------------------------------------- /src/dev/demo/hooks.clj: -------------------------------------------------------------------------------- 1 | (ns demo.hooks 2 | (:require [shadow.cljs.devtools.api :as api])) 3 | 4 | (defn dummy 5 | {:shadow.build/stage :flush} 6 | [state & args] 7 | (prn [::flush args]) 8 | state) 9 | -------------------------------------------------------------------------------- /src/dev/demo/http.clj: -------------------------------------------------------------------------------- 1 | (ns demo.http) 2 | 3 | (defn loud-404s [req] 4 | {:status 404 5 | :body "NOT FOUND YO!"}) 6 | 7 | (defn proxy-predicate [ex config] 8 | (tap> [:proxy-predicate ex config]) 9 | true) -------------------------------------------------------------------------------- /src/dev/demo/instrument.cljs: -------------------------------------------------------------------------------- 1 | (ns ^:dev/always demo.instrument 2 | (:require 3 | [demo.browser :as x] 4 | [cljs.spec.test.alpha :as st])) 5 | 6 | (defn ^:dev/after-load instrument [] 7 | (st/instrument) 8 | (js/console.log "instrument called") 9 | (x/bla 1) 10 | (x/bla "foo")) 11 | -------------------------------------------------------------------------------- /src/dev/demo/js_class.js: -------------------------------------------------------------------------------- 1 | goog.module('demo.js_class'); 2 | goog.module.declareLegacyNamespace(); 3 | 4 | // requires polyfills 5 | let [a, ...rest] = [1, 2, 3, 4, 5]; 6 | 7 | console.log("foo3"); 8 | 9 | class Foo { 10 | /** 11 | * @param {string=} a 12 | */ 13 | constructor(a) { 14 | /** 15 | * @type {string} 16 | */ 17 | this.a = a || "G7S"; 18 | } 19 | 20 | /** 21 | * @return {string} 22 | */ 23 | say() { 24 | return "Hello " + this.a; 25 | } 26 | } 27 | 28 | exports.a = a; 29 | 30 | exports.Foo = Foo; -------------------------------------------------------------------------------- /src/dev/demo/lib.cljs: -------------------------------------------------------------------------------- 1 | (ns demo.lib 2 | (:require ["which" :as w])) 3 | 4 | (js/console.log "demo.lib") 5 | 6 | (defn hello [] 7 | (w/sync "java" #js {:nothrow true})) 8 | 9 | -------------------------------------------------------------------------------- /src/dev/demo/macro.clj: -------------------------------------------------------------------------------- 1 | (ns demo.macro 2 | (:require [demo.macro-dep :as dep])) 3 | 4 | (defmacro foo [& body] 5 | (dep/foo)) 6 | -------------------------------------------------------------------------------- /src/dev/demo/macro.cljs: -------------------------------------------------------------------------------- 1 | (ns demo.macro 2 | (:require-macros [demo.macro :as m])) 3 | -------------------------------------------------------------------------------- /src/dev/demo/macro_dep.clj: -------------------------------------------------------------------------------- 1 | (ns demo.macro-dep) 2 | 3 | (defn foo [] 1) 4 | -------------------------------------------------------------------------------- /src/dev/demo/mixed.cljc: -------------------------------------------------------------------------------- 1 | (ns demo.mixed 2 | #?(:cljs (:require-macros [demo.mixed]))) 3 | 4 | 5 | ;; CLJ cannot compile JS only code 6 | (defn cljs-only [] 7 | (js/console.log "cljs-only doesn't compile in CLJ")) 8 | 9 | ;; so it needs to put into a reader conditional 10 | #?(:cljs 11 | (defn cljs-only [] 12 | (js/console.log "now CLJ is happy"))) 13 | 14 | ;; this will compile fine in CLJ and CLJS 15 | ;; so it does not need a reader conditional 16 | (defn this-is-shared [] 17 | :foo) 18 | 19 | ;; macros as CLJ only, so they also need to be inside areader conditional 20 | #?(:clj 21 | (defmacro hello-world [& args] 22 | :hello-world)) 23 | 24 | -------------------------------------------------------------------------------- /src/dev/demo/more-es6.js: -------------------------------------------------------------------------------- 1 | 2 | function bar(x) { 3 | return x; 4 | }; 5 | 6 | let foo = 1; 7 | 8 | export { bar, foo }; -------------------------------------------------------------------------------- /src/dev/demo/native.cljs: -------------------------------------------------------------------------------- 1 | (ns demo.native 2 | (:require ["react" :as r :refer (thing)] 3 | [demo.protocol :as dp] 4 | [clojure.string :as string] 5 | [clojure.set :as set])) 6 | 7 | ;; lots of native interop, not actually valid code, just for testing externs generator 8 | (set! *warn-on-infer* true) 9 | 10 | (thing) 11 | 12 | (.nested (.test (r/xyz))) 13 | (.bar r) 14 | 15 | (defn x [^js y] 16 | (.. y (jsFun) -jsProp (jsFunTwo))) 17 | 18 | (defn wrap-baz [x] 19 | (.baz x)) 20 | 21 | (js/foo.bar.xyz) 22 | (js/goog.object.set nil nil) 23 | (js/cljs.core.assoc nil :foo :bar) 24 | 25 | 26 | (defn thing [{:keys [foo] :as this}] 27 | (.componentDidUpdate ^js this)) 28 | 29 | (defn thing2 [simple] 30 | (.componentDidUpdate simple)) 31 | 32 | (deftype ShouldNotWarnAboutInfer [foo bar] 33 | Object 34 | (yo [x]) 35 | 36 | ILookup 37 | (-lookup [this key] 38 | ::fake)) 39 | 40 | (extend-protocol dp/SomeProtocol 41 | ShouldNotWarnAboutInfer 42 | (some-protocol-fn [this x] 43 | x)) 44 | 45 | (defrecord SomeRecord [x y]) 46 | 47 | (implements? dp/SomeProtocol (SomeRecord. 1 2)) 48 | 49 | (def empty-map {}) 50 | 51 | (def empty-set #{}) 52 | 53 | (def empty-vec []) 54 | 55 | (def empty-list (list)) 56 | 57 | 58 | (defn var-args [thing & more]) 59 | 60 | (defn arities 61 | ([a] a) 62 | ([a b] a) 63 | ([a b & c] a)) 64 | 65 | (reify dp/SomeProtocol 66 | (some-protocol-fn [this x] 67 | ::reify)) 68 | -------------------------------------------------------------------------------- /src/dev/demo/never_load.cljs: -------------------------------------------------------------------------------- 1 | (ns ^:dev/never-load demo.never-load) 2 | 3 | (js/console.warn "should never reload this") 4 | -------------------------------------------------------------------------------- /src/dev/demo/notify_plugin.clj: -------------------------------------------------------------------------------- 1 | (ns demo.notify-plugin 2 | (:require 3 | [clojure.core.async :as async] 4 | [shadow.jvm-log :as log] 5 | [shadow.cljs :as-alias m] 6 | [shadow.cljs.devtools.server.system-bus :as sys-bus] 7 | )) 8 | 9 | (def plugin 10 | {:requires-server true 11 | :depends-on [:system-bus] 12 | :start 13 | (fn [sys-bus] 14 | (log/debug ::start) 15 | (let [sub-chan (async/chan 512)] 16 | (sys-bus/sub sys-bus ::m/worker-broadcast sub-chan) 17 | {:chan sub-chan 18 | :thread 19 | (async/thread 20 | (loop [] 21 | (when-some [msg (async/ msg) to see exact structure of the msg data 23 | (case (:type msg) 24 | :build-start 25 | (prn [:build-started (:build-id msg)]) 26 | 27 | :build-complete 28 | (prn [:build-completed-successfully (:build-id msg)]) 29 | 30 | :build-failure 31 | (prn [:build-failed (:build-id msg)]) 32 | 33 | ;; ignore others (currently only :build-configure, only emitted when build config changes) 34 | nil) 35 | 36 | (recur))))})) 37 | :stop 38 | (fn [{:keys [chan thread] :as svc}] 39 | (log/debug ::stop) 40 | (async/close! chan) 41 | ;; wait for proper shutdown 42 | (async/ @timer .toTimeString (clojure.string/split " ") first)] 14 | [:div.example-clock time-str])) 15 | 16 | (defonce click-count (r/atom 0)) 17 | 18 | (defn clicker [] 19 | [:div.color-input 20 | {:on-click #(swap! click-count inc)} 21 | (str "clicks:" @click-count)]) 22 | 23 | (defn simple-example [] 24 | [:div 25 | [greeting "Hello world, it is now"] 26 | [clicker] 27 | [clock]]) 28 | 29 | (defn ^:export run [] 30 | (r/render [simple-example] 31 | (js/document.getElementById "app"))) 32 | 33 | (run) -------------------------------------------------------------------------------- /src/dev/demo/rel_require.cljs: -------------------------------------------------------------------------------- 1 | (ns demo.rel-require 2 | (:require ["./foo" :as foo])) 3 | 4 | (defn main [] 5 | (js/console.log "foo" foo)) -------------------------------------------------------------------------------- /src/dev/demo/repl.cljs: -------------------------------------------------------------------------------- 1 | (ns demo.repl 2 | (:require ["react" :as react])) 3 | 4 | 5 | (defn should-be-line-5 [] 6 | "yo") 7 | 8 | (js/console.log "demo.repl" {:foo ["bar"]}) 9 | -------------------------------------------------------------------------------- /src/dev/demo/rn.cljs: -------------------------------------------------------------------------------- 1 | (ns demo.rn 2 | (:require 3 | [shadow.react-native :refer (render-root)] 4 | ["react-native" :as rn] 5 | ["react" :as react])) 6 | 7 | (def styles 8 | ^js (-> {:container 9 | {:flex 1 10 | :backgroundColor "#fff" 11 | :alignItems "center" 12 | :justifyContent "center"} 13 | :title 14 | {:fontWeight "bold" 15 | :fontSize 24 16 | :color "blue"}} 17 | (clj->js) 18 | (rn/StyleSheet.create))) 19 | 20 | (defn bad-press [e] 21 | (js/console.log "pressed the bad button") 22 | (throw (ex-info "button pressed" {}))) 23 | 24 | (js/console.log "package.json just for fun" (js/require "../package.json")) 25 | 26 | (defn root [] 27 | (react/createElement rn/View #js {:style (.-container styles)} 28 | (react/createElement rn/Text #js {:style (.-title styles)} "Hello!") 29 | (let [comp (js/require "./foo.js")] 30 | (comp)) 31 | (react/createElement rn/Button #js {:onPress (fn [e] (bad-press e)) 32 | :title "error"}))) 33 | 34 | (defn start 35 | {:dev/after-load true} 36 | [] 37 | (render-root "TestCRNA" (root))) 38 | 39 | (defn init [] 40 | (start)) -------------------------------------------------------------------------------- /src/dev/demo/rn_foo.cljs: -------------------------------------------------------------------------------- 1 | (ns demo.rn-foo 2 | (:require 3 | ["react-native" :as rn] 4 | ["react" :as r])) 5 | 6 | (defn component [] 7 | (r/createElement rn/Text nil "Hello Foo!")) 8 | -------------------------------------------------------------------------------- /src/dev/demo/rule-breaker.js: -------------------------------------------------------------------------------- 1 | // filename does not match exported name 2 | // lots of stuff in the closure-library doesn't either so this needs to be ok 3 | goog.module("demo.didnt_follow_the_rules"); 4 | goog.module.declareLegacyNamespace(); 5 | 6 | exports.foo = 1; -------------------------------------------------------------------------------- /src/dev/demo/run_test.clj: -------------------------------------------------------------------------------- 1 | (ns demo.run-test) 2 | 3 | (defn fn1 [& args] 4 | (prn [:fn1 args])) 5 | 6 | (defn fn2 [& args] 7 | (prn [:fn2 args])) 8 | -------------------------------------------------------------------------------- /src/dev/demo/script.cljs: -------------------------------------------------------------------------------- 1 | (ns demo.script 2 | (:require 3 | ["http" :as http] 4 | ["request" :as req] 5 | ;; ["./cjs.js" :as cjs] 6 | [demo.js-class :refer (Foo)] 7 | ["./es6.js" :as es6] 8 | ["which" :as which])) 9 | 10 | (req "https://www.google.com" 11 | (fn [error res body] 12 | (prn [:error error]) 13 | (prn [:res res]) 14 | ;; (prn [:body body]) 15 | )) 16 | 17 | (prn [:which (which/sync "java" #js {:nothrow true})]) 18 | 19 | (defn request-handler [req res] 20 | (.end res "foo")) 21 | 22 | (defonce server-ref 23 | (volatile! nil)) 24 | 25 | (defn main [& args] 26 | (js/console.log "starting server") 27 | (es6/foo "bar") 28 | (let [server (http/createServer #(request-handler %1 %2))] 29 | 30 | (tap> [:hello-world js/process.env]) 31 | 32 | (.listen server 3000 33 | (fn [err] 34 | (if err 35 | (js/console.error "server start failed") 36 | (js/console.info "http server running")) 37 | )) 38 | 39 | (vreset! server-ref server) 40 | )) 41 | 42 | (defn start [] 43 | (js/console.warn "start called") 44 | (main)) 45 | 46 | (defn stop [done] 47 | (js/console.warn "stop called") 48 | (when-some [srv @server-ref] 49 | (.close srv 50 | (fn [err] 51 | (js/console.log "stop completed" err) 52 | (done))))) 53 | 54 | (js/console.log "__filename" js/__filename) 55 | -------------------------------------------------------------------------------- /src/dev/demo/selfhost/simple.cljs: -------------------------------------------------------------------------------- 1 | (ns demo.selfhost.simple 2 | (:require [cljs.js :as cljs] 3 | [cljs.env :as env] 4 | [shadow.cljs.bootstrap.browser :as boot] 5 | )) 6 | 7 | (defn print-result [{:keys [error value] :as result}] 8 | (js/console.log "result" result) 9 | (set! (.-innerHTML (js/document.getElementById "dump")) value)) 10 | 11 | (def code 12 | #_ " 13 | (ns simpleexample.core 14 | (:require [clojure.string :as str] 15 | [reagent.core :as r])) 16 | (defonce timer (r/atom (js/Date.))) 17 | (defonce time-color (r/atom \"#f34\")) 18 | (defonce time-updater (js/setInterval 19 | #(reset! timer (js/Date.)) 1000)) 20 | (defn greeting [message] 21 | [:h1 message]) 22 | (defn clock [] 23 | (let [time-str (-> @timer .toTimeString (str/split \" \") first)] 24 | [:div.example-clock 25 | {:style {:color @time-color}} 26 | time-str])) 27 | (defn color-input [] 28 | [:div.color-input 29 | \"Time color: \" 30 | [:input {:type \"text\" 31 | :value @time-color 32 | :on-change #(reset! time-color (-> % .-target .-value))}]]) 33 | (defn simple-example [] 34 | [:div 35 | [greeting \"Hello world, it is now\"] 36 | [clock] 37 | [color-input]]) 38 | (r/render [simple-example] (js/document.getElementById \"app\"))" 39 | "(require '[demo.lib :as x]) 40 | (js/console.log \"x\" (x/hello)) 41 | " 42 | ) 43 | 44 | (defonce compile-state-ref (env/default-compiler-env)) 45 | 46 | (defn compile-it [] 47 | (cljs/eval-str 48 | compile-state-ref 49 | code 50 | "[test]" 51 | {:eval cljs/js-eval 52 | :analyze-deps false 53 | :verbose true 54 | :load (partial boot/load compile-state-ref)} 55 | print-result)) 56 | 57 | (defn start [] 58 | (boot/init compile-state-ref 59 | {:path "/bootstrap"} 60 | compile-it)) 61 | 62 | (defn stop []) -------------------------------------------------------------------------------- /src/dev/demo/selfhost/worker.cljs: -------------------------------------------------------------------------------- 1 | (ns demo.selfhost.worker 2 | (:require [shadow.cljs.bootstrap.browser :as boot] 3 | [cljs.js :as cljs] 4 | [cljs.env :as env] 5 | [cognitect.transit :as transit])) 6 | 7 | (defn transit-read [txt] 8 | (let [r (transit/reader :json)] 9 | (transit/read r txt))) 10 | 11 | (defn transit-write [obj] 12 | (let [r (transit/writer :json)] 13 | (transit/write r obj))) 14 | 15 | (defonce compile-state-ref (env/default-compiler-env)) 16 | 17 | (defn post-message [obj] 18 | (js/postMessage (transit-write obj))) 19 | 20 | (defmulti do-request :action :default ::default) 21 | 22 | (defmethod do-request ::default [msg] 23 | (js/console.log "unknown action" msg)) 24 | 25 | (defmethod do-request :compile [{:keys [code]}] 26 | (cljs/eval-str 27 | compile-state-ref 28 | code 29 | "[test]" 30 | {:analyze-deps false 31 | :eval (fn [{:keys [source] :as x}] 32 | (js/console.log "eval" x) 33 | (post-message {:action :eval :source source})) 34 | :load (partial boot/load compile-state-ref)} 35 | (fn [result] 36 | (js/console.log "result" result)))) 37 | 38 | (defn ready [] 39 | (post-message {:action :ready}) 40 | (set! (.-onmessage js/self) 41 | (fn [e] 42 | (let [data (transit-read (.-data e))] 43 | (do-request data)) 44 | ))) 45 | 46 | (boot/init compile-state-ref 47 | {:path "/bootstrap" 48 | :load (fn [{:keys [type source] :as load-info}] 49 | (when (= :js type) 50 | ;; FIXME: host does not need to eval $macros 51 | (post-message {:action :shadow-load :load-info load-info})))} 52 | ready) 53 | -------------------------------------------------------------------------------- /src/dev/demo/sm_before.cljs: -------------------------------------------------------------------------------- 1 | (ns demo.sm-before) 2 | 3 | (js/console.log "demo.sm-before") 4 | -------------------------------------------------------------------------------- /src/dev/demo/sm_main.cljs: -------------------------------------------------------------------------------- 1 | (ns demo.sm-main 2 | (:require [demo.sm-before] 3 | ["js-sm-test"])) 4 | 5 | (js/console.log "demo.sm-main") 6 | -------------------------------------------------------------------------------- /src/dev/demo/stuff.cljs: -------------------------------------------------------------------------------- 1 | (ns demo.stuff 2 | (:require ["./foo" :as foo])) 3 | 4 | (defmulti foo ::bar) 5 | -------------------------------------------------------------------------------- /src/dev/demo/test.md: -------------------------------------------------------------------------------- 1 | # hello world! -------------------------------------------------------------------------------- /src/dev/demo/test_fail.cljs: -------------------------------------------------------------------------------- 1 | (ns demo.test-fail 2 | (:require [cljs.test :refer [deftest is]])) 3 | 4 | (deftest a-failing-test 5 | (is (= 1 2) "it should fail") 6 | 7 | 123 8 | -------------------------------------------------------------------------------- /src/dev/demo/type.cljs: -------------------------------------------------------------------------------- 1 | (ns demo.type) 2 | 3 | (deftype Foo [a b] 4 | Object 5 | (foo [this x] 6 | x)) 7 | -------------------------------------------------------------------------------- /src/dev/demo/warnings.cljs: -------------------------------------------------------------------------------- 1 | (ns demo.warnings) 2 | 3 | (defn x [foo] 4 | foo) 5 | 6 | i-dont-exist 7 | 8 | (def extremely-long line) 9 | 10 | (def x abc) 11 | 12 | (+ "a" 1) 13 | 14 | (have-some-more-warnings foo) 15 | 16 | (defn main []) -------------------------------------------------------------------------------- /src/dev/demo/with_underscore.cljs: -------------------------------------------------------------------------------- 1 | (ns demo.with_underscore) 2 | -------------------------------------------------------------------------------- /src/dev/demo/worker.cljs: -------------------------------------------------------------------------------- 1 | (ns demo.worker) 2 | 3 | ;; this ns in only executed by the worker 4 | 5 | (defn ^:dev/after-load start [] 6 | (js/console.log "worker reload")) 7 | 8 | (defn init [] 9 | (js/console.log "worker started") 10 | (js/postMessage (pr-str (assoc {:x 1} :y 2)))) 11 | 12 | 13 | -------------------------------------------------------------------------------- /src/dev/demo/zombie.cljs: -------------------------------------------------------------------------------- 1 | (ns demo.zombie 2 | (:require 3 | [cljs.test :refer (deftest is)])) 4 | 5 | (defn init [] 6 | ;; just some code to keep the CLJS collections alive 7 | (js/console.log [:hello {:who "World!"}])) 8 | 9 | (deftest my-test 10 | (is (= :super :cool))) 11 | -------------------------------------------------------------------------------- /src/dev/git_tags.clj: -------------------------------------------------------------------------------- 1 | (ns git-tags 2 | (:require 3 | [clojure.java.shell :refer (sh)] 4 | [clojure.string :as str])) 5 | 6 | 7 | (defn git-tags [] 8 | (-> (sh "git" "tag" "--list") 9 | (get :out) 10 | (str/split #"\n") 11 | (set))) 12 | 13 | (comment 14 | (git-tags)) 15 | 16 | (defn -main [& args]) 17 | -------------------------------------------------------------------------------- /src/dev/log4j.properties.shutup: -------------------------------------------------------------------------------- 1 | log4j.rootLogger=INFO, console 2 | log4j.appender.console=org.apache.log4j.ConsoleAppender 3 | log4j.appender.console.layout=org.apache.log4j.PatternLayout 4 | log4j.appender.console.layout.ConversionPattern=[%d{HH:mm:ss,SSS}] %m%n 5 | 6 | log4j.logger.shadow=DEBUG 7 | -------------------------------------------------------------------------------- /src/dev/repl.clj: -------------------------------------------------------------------------------- 1 | (ns repl 2 | (:require 3 | [shadow.cljs.devtools.server :as server] 4 | [shadow.cljs.devtools.api :as cljs] 5 | [shadow.cljs.devtools.cli] 6 | [shadow.cljs.devtools.server.fs-watch :as fs-watch] 7 | [clojure.java.io :as io] 8 | [build])) 9 | 10 | (defonce css-watch-ref (atom nil)) 11 | 12 | (comment 13 | (generate-css)) 14 | 15 | (defn start [_] 16 | (server/start!) 17 | 18 | ;; (cljs/watch :ui) 19 | 20 | (build/css-release) 21 | 22 | (reset! css-watch-ref 23 | (fs-watch/start 24 | {} 25 | [(io/file "src" "main")] 26 | ["cljs" "cljc" "clj"] 27 | (fn [updates] 28 | (try 29 | (build/css-release) 30 | (catch Exception e 31 | (prn [:css-failed e]))) 32 | ))) 33 | 34 | ::started) 35 | 36 | (defn stop [] 37 | (when-some [css-watch @css-watch-ref] 38 | (fs-watch/stop css-watch)) 39 | 40 | (server/stop!) 41 | ::stopped) 42 | 43 | (defn go [] 44 | (stop) 45 | (start nil)) -------------------------------------------------------------------------------- /src/dev/shadow/insight/plugin.clj: -------------------------------------------------------------------------------- 1 | (ns shadow.insight.plugin 2 | (:require 3 | [shadow.insight.remote-ext :as insight-ext])) 4 | 5 | (def plugin 6 | {:requires-server true 7 | :depends-on [:clj-runtime :clj-runtime-obj-support] 8 | :start insight-ext/start 9 | :stop insight-ext/stop}) 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /src/dev/shadow/insight/runtime.cljc: -------------------------------------------------------------------------------- 1 | (ns shadow.insight.runtime) 2 | 3 | (defprotocol IPlanAware 4 | (-proceed-with-plan [this runtime-ext exec-ctx])) 5 | 6 | ;; trying to keep this file as generic as possible 7 | ;; these represent commands and their implementation is host-specific 8 | ;; remote-ext depends on this, so can't have things here 9 | ;; trying to keep this separate, so just the API for insight files is here 10 | 11 | (deftype SwitchToLocal []) 12 | 13 | (defn in-local [] 14 | (->SwitchToLocal)) 15 | 16 | (deftype SwitchToRemote [opts]) 17 | 18 | (defn in-remote [opts] 19 | (->SwitchToRemote opts)) 20 | -------------------------------------------------------------------------------- /src/dev/shadow/insight/web.clj: -------------------------------------------------------------------------------- 1 | (ns shadow.insight.web 2 | (:require 3 | [hiccup.page :refer (html5)] 4 | [shadow.cljs.devtools.server.supervisor :as super] 5 | [shadow.cljs.devtools.server.web.common :as common] 6 | [shadow.cljs.devtools.server.worker :as worker] 7 | [shadow.http.router :as http] 8 | [shadow.jvm-log :as log])) 9 | 10 | (defn iframe 11 | [{:keys [runtime supervisor] :as req} build-id] 12 | (let [worker 13 | (or (super/get-worker supervisor build-id) 14 | 15 | ;; FIXME: get base config from shadow-cljs.edn, might need custom options 16 | (let [config 17 | {:build-id build-id 18 | :target :esm 19 | :modules {:main {:init-fn 'shadow.insight.ui/init}} 20 | :output-dir (str ".shadow-cljs/builds/" (name build-id) "/js")}] 21 | 22 | (log/debug ::insight-ui-start config) 23 | 24 | ;; FIXME: access to CLI opts from server start? 25 | (-> (super/start-worker supervisor config {}) 26 | (worker/start-autobuild))))] 27 | 28 | (worker/sync! worker) 29 | 30 | {:status 200 31 | :headers {"content-type" "text/html; charset=utf-8"} 32 | :body 33 | (html5 34 | {:lang "en"} 35 | [:head 36 | [:script {:type "module" :src (str "/cache/" (name build-id) "/js/main.js")}] 37 | [:title "shadow.insight"] 38 | [:meta {:name "viewport" :content "width=device-width, initial-scale=1"}]] 39 | [:body])})) 40 | 41 | 42 | (defn handler [req] 43 | (-> req 44 | (http/route 45 | (:GET "/iframe/{build-id:keyword}" iframe build-id) 46 | common/not-found))) 47 | -------------------------------------------------------------------------------- /src/dev/shadow_test.clj: -------------------------------------------------------------------------------- 1 | (ns shadow-test 2 | (:require 3 | [clojure.java.io :refer [file]] 4 | [nrepl.core :as nrepl])) 5 | 6 | (defn message [s msg] 7 | (-> s 8 | (nrepl/message msg) 9 | (nrepl/combine-responses) 10 | prn)) 11 | 12 | (defn require-ns [{:keys [path-ns port build-id]}] 13 | (let [transport (nrepl/connect :port port) 14 | session (-> transport 15 | (nrepl/client 1000) 16 | (nrepl/client-session))] 17 | (message session {:op :eval 18 | :code (pr-str 19 | `(cider.piggieback/cljs-repl 20 | ~build-id))}) 21 | (message session {:op :eval 22 | :ns "cljs.user" 23 | :code (str "(ns cljs.user (:require " path-ns " ))")}) 24 | (.close transport))) 25 | 26 | (defn touch-file [file-path] 27 | (-> (file file-path) 28 | (.setLastModified (System/currentTimeMillis)))) 29 | 30 | (defn -main [path path-ns port build-id] 31 | (let [config 32 | {:path path 33 | :path-ns path-ns 34 | :port (Integer/parseInt port) 35 | :build-id (keyword build-id)}] 36 | 37 | (prn config) 38 | (touch-file (:path config)) 39 | (Thread/sleep 100) 40 | (require-ns config))) 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /src/dev/user.clj: -------------------------------------------------------------------------------- 1 | (ns user) 2 | 3 | ;; just using this to prevent any other user.clj from every being loaded -------------------------------------------------------------------------------- /src/js/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "plugins": ["@babel/plugin-transform-react-jsx"] 3 | } 4 | -------------------------------------------------------------------------------- /src/js/convert.sh: -------------------------------------------------------------------------------- 1 | npx babel . -d ../gen --source-maps inline -------------------------------------------------------------------------------- /src/js/demo/myComponent.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | function myComponent() { 4 | return

JSX!

; 5 | } 6 | 7 | 8 | export { myComponent }; -------------------------------------------------------------------------------- /src/main/cljs/test_stubs.clj: -------------------------------------------------------------------------------- 1 | (ns cljs.test-stubs 2 | (:require [cljs.test])) 3 | 4 | (defmacro is [& body] 5 | true) 6 | 7 | (defmacro are [& body] 8 | true) 9 | 10 | (defmacro deftest [& body] 11 | nil) 12 | 13 | (defmacro testing [& body] 14 | nil) 15 | 16 | (defmacro async [& body] 17 | nil) 18 | 19 | (defmacro run-tests [& body] 20 | nil) 21 | 22 | (defmacro run-test [& body] 23 | nil) 24 | 25 | (defmacro run-all-tests [& body] 26 | nil) 27 | 28 | (defmacro test-all-vars [& body] 29 | nil) 30 | 31 | (defmacro use-fixtures [& body] 32 | nil) 33 | 34 | (defmacro test-ns [& body] 35 | nil) -------------------------------------------------------------------------------- /src/main/cljs/test_stubs.cljs: -------------------------------------------------------------------------------- 1 | (ns cljs.test-stubs 2 | (:require-macros [cljs.test-stubs])) 3 | 4 | (defn empty-env 5 | ([]) 6 | ([reporter])) 7 | 8 | (defn test-var [v]) 9 | 10 | (defn test-vars-block [vars]) 11 | 12 | (defn test-vars [vars]) 13 | 14 | (defn successful? [summary]) 15 | 16 | -------------------------------------------------------------------------------- /src/main/shadow/boot/esm.js: -------------------------------------------------------------------------------- 1 | var SHADOW_ENV = $CLJS.SHADOW_ENV = (function() { 2 | var env = {}; 3 | 4 | var loadedFiles = env.loadedFiles = {}; 5 | 6 | env.setLoaded = function(name) { 7 | loadedFiles[name] = true; 8 | }; 9 | 10 | env.load = function(opts, paths) { 11 | paths.forEach(function(name) { 12 | env.setLoaded(name); 13 | }); 14 | }; 15 | 16 | env.isLoaded = function(name) { 17 | return loadedFiles[name] || false; 18 | } 19 | 20 | return env; 21 | })(); 22 | -------------------------------------------------------------------------------- /src/main/shadow/boot/npm_module.js: -------------------------------------------------------------------------------- 1 | var SHADOW_ENV = $CLJS.SHADOW_ENV = (function() { 2 | var env = {}; 3 | 4 | var loadedFiles = env.loadedFiles = {}; 5 | 6 | env.setLoaded = function(name) { 7 | loadedFiles[name] = true; 8 | }; 9 | 10 | env.load = function(opts, paths) { 11 | paths.forEach(function(name) { 12 | env.setLoaded(name); 13 | }); 14 | }; 15 | 16 | env.isLoaded = function(name) { 17 | return loadedFiles[name] || false; 18 | } 19 | 20 | return env; 21 | })(); 22 | -------------------------------------------------------------------------------- /src/main/shadow/boot/react-native.js: -------------------------------------------------------------------------------- 1 | var SHADOW_ENV = $CLJS.SHADOW_ENV = (function() { 2 | var env = {}; 3 | 4 | var loadedFiles = {}; 5 | 6 | env.setLoaded = function(name) { 7 | loadedFiles[name] = true; 8 | }; 9 | 10 | env.load = function(opts, paths) { 11 | paths.forEach(function(name) { 12 | env.setLoaded(name); 13 | }); 14 | }; 15 | 16 | env.isLoaded = function(name) { 17 | // this is only used by live-reload checking if it should reload a file 18 | // since all files will always be loaded we don't really need to track this? 19 | return true; 20 | // return loadedFiles[name] || false; 21 | } 22 | 23 | env.evalLoad = function(name, code) { 24 | goog.globalEval(code); 25 | }; 26 | 27 | return env; 28 | })(); 29 | 30 | // object of require->fn to "trigger" the actual require 31 | // mostly to remain semantics of "when" something is included 32 | // rather than forcefully including everything at the top of the file 33 | $CLJS.shadow$js = {}; 34 | $CLJS.shadow$jsRequire = function(name) { 35 | var fn = $CLJS.shadow$js[name]; 36 | 37 | if (typeof fn == 'function') { 38 | return fn(); 39 | } else { 40 | throw new Error("require " + name + " not found. If you require'd this manually you may need to reload the app so metro can process it.") 41 | } 42 | }; 43 | 44 | // fake require function since metro replaced all static require calls already 45 | // and require is actually undefined otherwise. Ideally CLJS would have emitted 46 | // another function call as well but that would require adjusting the compiler more 47 | global.require = function(name) { 48 | return $CLJS.shadow$jsRequire(name); 49 | }; 50 | 51 | // make js/global accessible in eval'd sources since it isn't actually a global 52 | global.global = global; -------------------------------------------------------------------------------- /src/main/shadow/boot/static.js: -------------------------------------------------------------------------------- 1 | var SHADOW_ENV = $CLJS.SHADOW_ENV = (function() { 2 | var env = {}; 3 | 4 | var loadedFiles = env.loadedFiles = {}; 5 | 6 | env.setLoaded = function(name) { 7 | loadedFiles[name] = true; 8 | }; 9 | 10 | env.load = function(opts, paths) { 11 | paths.forEach(function(name) { 12 | env.setLoaded(name); 13 | }); 14 | }; 15 | 16 | env.isLoaded = function(name) { 17 | // this is only used by live-reload checking if it should reload a file 18 | // since all files will always be loaded we don't really need to track this? 19 | return true; 20 | // return loadedFiles[name] || false; 21 | } 22 | 23 | return env; 24 | })(); 25 | -------------------------------------------------------------------------------- /src/main/shadow/boot/worker.js: -------------------------------------------------------------------------------- 1 | var SHADOW_ENV = (function () { 2 | var loadedFiles = {}; 3 | 4 | var env = {}; 5 | 6 | var scriptBase = self.location.href; 7 | scriptBase = scriptBase.substring(0, scriptBase.lastIndexOf("/")) + "/cljs-runtime/"; 8 | env.scriptBase = scriptBase; 9 | 10 | env.load = function (opts, paths) { 11 | paths.forEach(function (path) { 12 | if (!loadedFiles[path]) { 13 | loadedFiles[path] = true; 14 | var uri = 'cljs-runtime/' + path; 15 | importScripts(uri); 16 | } 17 | }); 18 | } 19 | 20 | env.isLoaded = function (path) { 21 | return loadedFiles[path] || false; // false is better than undefined 22 | } 23 | 24 | env.setLoaded = function(path) { 25 | loadedFiles[path] = true; 26 | } 27 | 28 | env.evalLoad = function(path, sourceMap, code) { 29 | loadedFiles[path] = true; 30 | code += ("\n//# sourceURL=" + scriptBase + path); 31 | if (sourceMap) { 32 | code += ("\n//# sourceMappingURL=" + scriptBase + path + ".map"); 33 | } 34 | try { 35 | goog.globalEval(code); 36 | } catch (e) { 37 | console.warn("failed to load", path, e); 38 | } 39 | } 40 | 41 | return env; 42 | }).call(this); -------------------------------------------------------------------------------- /src/main/shadow/build/async.clj: -------------------------------------------------------------------------------- 1 | (ns shadow.build.async 2 | (:import [java.util.concurrent ExecutorService])) 3 | 4 | (defn queue-task 5 | [{:keys [executor pending-tasks-ref] :as state} fn] 6 | (if-not executor 7 | (fn) 8 | ;; FIXME: no backpressure, can potentially eat up a whole lot of memory 9 | ;; if too many tasks get queued before actually completing 10 | (let [future 11 | (.submit 12 | ^ExecutorService executor 13 | ;; enforce the nil return value, would otherwise maybe retain 14 | ;; some unnecessary state in form of the return value 15 | ^Callable (bound-fn [] (fn) nil))] 16 | (swap! pending-tasks-ref conj future))) 17 | state) 18 | 19 | (defn wait-for-pending-tasks! 20 | [{:keys [pending-tasks-ref] :as state}] 21 | ;; using an atom for this feels so dirty 22 | ;; but return values are ignored anyways so it doesn't matter too much 23 | (swap! pending-tasks-ref 24 | (fn [tasks] 25 | (run! deref tasks) 26 | [])) 27 | state) 28 | -------------------------------------------------------------------------------- /src/main/shadow/build/cache.clj: -------------------------------------------------------------------------------- 1 | (ns shadow.build.cache 2 | (:require [cognitect.transit :as transit]) 3 | (:import (java.io File FileOutputStream FileInputStream ByteArrayOutputStream) 4 | (java.net URL) 5 | (cljs.tagged_literals JSValue) 6 | [java.util.regex Pattern])) 7 | 8 | (defn write-stream [out data] 9 | (let [w (transit/writer out :json 10 | {:handlers 11 | {URL 12 | (transit/write-handler "url" str) 13 | File 14 | (transit/write-handler "file" #(.getAbsolutePath %)) 15 | JSValue 16 | (transit/write-handler "js-value" #(.-val %)) 17 | Pattern 18 | (transit/write-handler "regexp" 19 | (fn [re] 20 | [(.pattern re) (.flags re)])) 21 | }})] 22 | (transit/write w data))) 23 | 24 | (defn write-file [^File file data] 25 | (with-open [out (FileOutputStream. file)] 26 | (write-stream out data))) 27 | 28 | (defn write-str [data] 29 | (let [out (ByteArrayOutputStream.)] 30 | (write-stream out data) 31 | (.toString out "UTF-8"))) 32 | 33 | (defn read-cache [^File file] 34 | {:pre [(.exists file)]} 35 | (with-open [in (FileInputStream. file)] 36 | (let [r (transit/reader in :json 37 | {:handlers 38 | {"url" 39 | (transit/read-handler #(URL. %)) 40 | "file" 41 | (transit/read-handler #(File. %)) 42 | "js-value" 43 | (transit/read-handler #(JSValue. %)) 44 | "regexp" 45 | (transit/read-handler 46 | (fn [[pattern flags]] 47 | (Pattern/compile pattern flags))) 48 | }})] 49 | (transit/read r) 50 | ))) 51 | 52 | 53 | -------------------------------------------------------------------------------- /src/main/shadow/build/closure/FindSurvivingRequireCalls.java: -------------------------------------------------------------------------------- 1 | package shadow.build.closure; 2 | 3 | import com.google.javascript.jscomp.*; 4 | import com.google.javascript.rhino.Node; 5 | 6 | import java.util.HashSet; 7 | import java.util.Set; 8 | 9 | public class FindSurvivingRequireCalls extends NodeTraversal.AbstractPostOrderCallback { 10 | 11 | final Set survivors = new HashSet<>(); 12 | 13 | @Override 14 | public void visit(NodeTraversal t, Node node, Node parent) { 15 | if (node.isCall() && node.getChildCount() == 2) { 16 | Node name = node.getFirstChild(); 17 | Node arg = node.getSecondChild(); 18 | 19 | Node refName; 20 | 21 | if (name.isName()) { 22 | refName = name; 23 | } else if (name.isGetProp() && name.getFirstChild().isName()) { 24 | refName = name.getFirstChild(); 25 | } else { 26 | return; 27 | } 28 | 29 | String originalName = refName.getOriginalName(); 30 | 31 | if (originalName != null && "require".equals(originalName)) { 32 | if (arg.isString()) { 33 | survivors.add(arg.getString()); 34 | } else if (arg.isNumber()) { 35 | survivors.add(((Double)arg.getDouble()).longValue()); 36 | } 37 | } 38 | } 39 | } 40 | 41 | public static Set find(AbstractCompiler compiler, Node node) { 42 | FindSurvivingRequireCalls visitor = new FindSurvivingRequireCalls(); 43 | NodeTraversal.traverse(compiler, node, visitor); 44 | return visitor.survivors; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/main/shadow/build/config.clj: -------------------------------------------------------------------------------- 1 | (ns shadow.build.config 2 | (:require [clojure.spec.alpha :as s])) 3 | 4 | (s/def ::build-id keyword?) 5 | 6 | (s/def ::target 7 | #(or (simple-keyword? %) 8 | (symbol? %))) 9 | 10 | (s/def ::build-hook 11 | (s/cat 12 | :hook-sym qualified-symbol? 13 | :hook-args (s/* any?) 14 | )) 15 | 16 | (s/def ::build-hooks 17 | (s/coll-of ::build-hook :kind vector?)) 18 | 19 | (defmulti target-spec :target :default ::default) 20 | 21 | (defmethod target-spec ::default [_] 22 | (s/spec any?)) 23 | 24 | (s/def ::build 25 | (s/keys 26 | :req-un 27 | [::build-id 28 | ::target] 29 | :opt-un 30 | [::build-hooks])) 31 | 32 | (s/def ::build+target 33 | (s/and 34 | ::build 35 | (s/multi-spec target-spec :target))) 36 | 37 | ;; deps.cljs specs 38 | 39 | (s/def ::file-min string?) 40 | 41 | (s/def ::file string?) 42 | 43 | ;; probably vector or set, doesn't matter 44 | (s/def ::externs (s/coll-of string? :distinct true)) 45 | (s/def ::provides (s/coll-of string? :distinct true)) 46 | (s/def ::requires (s/coll-of string? :distinct true)) 47 | 48 | (s/def ::foreign-lib 49 | (s/keys 50 | :opt-un 51 | [::file-min 52 | ::file 53 | ::externs 54 | ::provides 55 | ::requires])) 56 | 57 | (s/def ::foreign-libs 58 | (s/coll-of ::foreign-lib :distinct true)) 59 | 60 | (s/def ::deps-cljs 61 | (s/keys 62 | :opt-un 63 | [::externs 64 | ::foreign-libs])) -------------------------------------------------------------------------------- /src/main/shadow/build/css.clj: -------------------------------------------------------------------------------- 1 | (ns shadow.build.css 2 | (:require [clojure.java.io :as io] 3 | [clojure.string :as str] 4 | [shadow.build :as-alias build] 5 | [shadow.build.data :as data]) 6 | (:import [java.io File])) 7 | 8 | (defn extract-hook 9 | {::build/stage :flush} 10 | ([build-state] 11 | (extract-hook build-state {})) 12 | ([{::build/keys [mode] :as build-state} opts] 13 | (reduce 14 | (fn [build-state {:keys [module-id sources] :as x}] 15 | (let [asset-files 16 | (->> sources 17 | (map (fn [src-id] 18 | (get-in build-state [:sources src-id]))) 19 | (filter :asset) 20 | (map :file) 21 | (filter #(str/ends-with? (.getName ^File %) ".css")) 22 | (vec))] 23 | 24 | (when (seq asset-files) 25 | (let [css 26 | (->> asset-files 27 | (map (fn [file] 28 | (str (when (= :dev mode) 29 | (str "/** -- " (.getAbsolutePath file) " -- */\n")) 30 | (slurp file)))) 31 | (str/join "\n")) 32 | 33 | css-name 34 | (str (name module-id) ".css") 35 | 36 | out 37 | (if-some [out-dir (:output-dir opts)] 38 | (io/file out-dir css-name) 39 | (data/output-file build-state css-name))] 40 | 41 | (spit out css)))) 42 | 43 | build-state) 44 | build-state 45 | (:build-modules build-state)))) 46 | -------------------------------------------------------------------------------- /src/main/shadow/build/targets/external_boilerplate.js: -------------------------------------------------------------------------------- 1 | global.shadow$bridge = function shadow$bridge(name) { 2 | var ret = ALL[name]; 3 | 4 | if (ret === undefined) { 5 | throw new Error("Dependency: " + name + " not provided by external JS. Do you maybe need a recompile?"); 6 | } 7 | 8 | return ret; 9 | }; 10 | 11 | shadow$bridge.ALL = ALL; -------------------------------------------------------------------------------- /src/main/shadow/build/targets/graaljs_bootstrap.js: -------------------------------------------------------------------------------- 1 | function graaljs_async_not_supported() { 2 | // FIXME: I'm hesitant to introduce threads from inside the JS context 3 | // need to figure out some kind of event loop from the JVM side 4 | throw new Error("async functions not supported in graaljs engine."); 5 | } 6 | 7 | function setInterval() { 8 | graaljs_async_not_supported(); 9 | } 10 | 11 | function clearInterval(future) { 12 | graaljs_async_not_supported(); 13 | } 14 | 15 | function setTimeout() { 16 | graaljs_async_not_supported(); 17 | } 18 | 19 | function clearTimeout() { 20 | graaljs_async_not_supported(); 21 | } 22 | 23 | function setImmediate() { 24 | graaljs_async_not_supported(); 25 | } 26 | 27 | function clearImmediate(future) { 28 | graaljs_async_not_supported(); 29 | } 30 | -------------------------------------------------------------------------------- /src/main/shadow/build/targets/npm_module_goog_overrides.js: -------------------------------------------------------------------------------- 1 | 2 | var originalGoogExportPath = goog.exportPath_; 3 | 4 | goog.exportPath_ = function(name, object, overwriteImplicit, objectToExportTo) { 5 | // must keep the export to global for things like (goog/exportSymbol js/React ...) 6 | originalGoogExportPath(name, object, overwriteImplicit, objectToExportTo); 7 | // goog.module.declareLegacyNamespace() otherwise only exports to global but we need it on the $CLJS object 8 | if (goog.isInModuleLoader_()) { 9 | originalGoogExportPath(name, object, overwriteImplicit, $CLJS); 10 | } 11 | } 12 | 13 | goog.provide = function(name) { 14 | return originalGoogExportPath(name, undefined, undefined, $CLJS); 15 | }; 16 | 17 | 18 | // in goog.module this needs to have a return value 19 | // the getObjectByName will only find modules that declareLegacyNamespace 20 | // otherwise get the module directly. can't use default goog.require since 21 | // we are never using the debug loader and it never has a return value in that case 22 | goog.require = function(name) { 23 | return goog.getObjectByName(name, $CLJS) || goog.module.getInternal_(name); 24 | }; 25 | -------------------------------------------------------------------------------- /src/main/shadow/build/targets/umd_exports.txt: -------------------------------------------------------------------------------- 1 | (function(root, factory) { 2 | if (typeof define === "function" && define.amd) { 3 | define([], factory); 4 | } else if (typeof module === "object" && module.exports) { 5 | module.exports = factory(); 6 | } else { 7 | root.returnExports = factory(); 8 | } 9 | })(this, function() { 10 | var shadow$umd$export = null; 11 | 12 | //CLJS-HERE 13 | 14 | return shadow$umd$export; 15 | }); 16 | -------------------------------------------------------------------------------- /src/main/shadow/build/targets/umd_exports_dev.txt: -------------------------------------------------------------------------------- 1 | (function (root, factory) { 2 | if (typeof define === 'function' && define.amd) { 3 | define([], factory); 4 | } else if (typeof module === 'object' && module.exports) { 5 | module.exports = factory(); 6 | } else { 7 | root.returnExports = factory(); 8 | } 9 | })(this, function () { 10 | //CLJS-HERE 11 | 12 | return shadow.umd_helper.get_exports(); 13 | }); -------------------------------------------------------------------------------- /src/main/shadow/build/test_util.clj: -------------------------------------------------------------------------------- 1 | (ns shadow.build.test-util 2 | (:require [shadow.build.data :as data] 3 | [shadow.build.classpath :as cp] 4 | [shadow.cljs.util :as util] 5 | [clojure.java.io :as io])) 6 | 7 | (defn find-test-namespaces [{:keys [classpath] :as state} config] 8 | (let [{:keys [namespaces ns-regexp exclude test-paths] :or {ns-regexp "-test$" exclude #{}}} 9 | config 10 | 11 | ns-regexp 12 | (re-pattern ns-regexp)] 13 | 14 | (if (seq namespaces) 15 | namespaces 16 | (->> (cp/find-cljs-namespaces-in-files 17 | classpath 18 | (when (seq test-paths) 19 | (map io/file test-paths))) 20 | (filter (fn [ns] 21 | (re-find ns-regexp (str ns)))) 22 | (remove exclude) 23 | (sort) 24 | (into []))))) 25 | 26 | (defn inject-extra-requires 27 | [{::keys [runner-ns test-namespaces] :as state}] 28 | {:pre [(symbol? runner-ns) 29 | (coll? test-namespaces) 30 | (every? symbol? test-namespaces)]} 31 | 32 | ;; since the runner doesn't explicitly depend on the test namespaces 33 | ;; it may start compiling before they actually complete 34 | ;; which is a problem when the runner-ns uses macros that inspect the 35 | ;; analyzer data to discover tests since they may still be pending 36 | (let [runner-rc-id (data/get-source-id-by-provide state runner-ns)] 37 | 38 | (-> state 39 | (update-in [:sources runner-rc-id] assoc :extra-requires (set test-namespaces))))) 40 | 41 | 42 | (defn configure-common [state] 43 | (assoc-in state [:compiler-options :load-tests] true)) -------------------------------------------------------------------------------- /src/main/shadow/cljs/devtools/cli_info.clj: -------------------------------------------------------------------------------- 1 | (ns shadow.cljs.devtools.cli-info) 2 | 3 | (defn find-version-from-pom [pom-xml] 4 | (let [[_ version :as m] 5 | (->> (slurp pom-xml) 6 | (re-find #"([^<]+)"))] 7 | (when m 8 | version))) 9 | 10 | (defn find-version [] 11 | ;; basically io/resource, just trying to keep this ns lean and fast starting 12 | (let [pom-xml (-> (Thread/currentThread) 13 | (.getContextClassLoader) 14 | (.getResource "META-INF/maven/thheller/shadow-cljs/pom.xml"))] 15 | 16 | (if (nil? pom-xml) 17 | "" 18 | (find-version-from-pom pom-xml)))) 19 | 20 | (defn -main [& args] 21 | (println "shadow-cljs version: " (find-version))) 22 | -------------------------------------------------------------------------------- /src/main/shadow/cljs/devtools/client/browser_repl.cljs: -------------------------------------------------------------------------------- 1 | (ns shadow.cljs.devtools.client.browser-repl 2 | (:require [shadow.dom :as dom])) 3 | 4 | (def log-node (dom/by-id "log")) 5 | 6 | (let [actual-print-fn 7 | cljs.core/*print-fn*] 8 | 9 | (set-print-fn! 10 | (fn [s] 11 | (dom/append log-node (str s "\n")) 12 | (actual-print-fn s)))) 13 | -------------------------------------------------------------------------------- /src/main/shadow/cljs/devtools/client/node_repl.cljs: -------------------------------------------------------------------------------- 1 | (ns shadow.cljs.devtools.client.node-repl 2 | (:require [shadow.cljs.devtools.client.node :as node] 3 | [shadow.cljs.devtools.client.console])) ;; for --inspect, doesn't hurt otherwise 4 | 5 | (defn uncaught-exception [e origin] 6 | (tap> [:uncaught-exception e origin]) 7 | (js/console.warn "---- UNCAUGHT EXCEPTION --------------") 8 | (js/console.warn e) 9 | (js/console.warn "--------------------------------------")) 10 | 11 | (defn unhandled-rejection [e promise] 12 | (tap> [:unhandled-rejection e promise]) 13 | (js/console.warn "---- UNHANDLED REJECTION --------------") 14 | (js/console.warn e) 15 | (js/console.warn "--------------------------------------")) 16 | 17 | ;; repl related things will already have executed and started to connect (async) 18 | (defn main [] 19 | ;; (js/process.on "uncaughtException" uncaught-exception) 20 | ;; not doing this, so we only attach this once on startup but 21 | ;; can redefine it during operation by redefining the var 22 | 23 | (js/process.on "uncaughtException" 24 | (fn [e origin] 25 | (uncaught-exception e origin))) 26 | 27 | (js/process.on "unhandledRejection" 28 | (fn [e promise] 29 | (unhandled-rejection e promise)))) -------------------------------------------------------------------------------- /src/main/shadow/cljs/devtools/client/websocket.cljs: -------------------------------------------------------------------------------- 1 | (ns shadow.cljs.devtools.client.websocket 2 | (:require 3 | [shadow.cljs.devtools.client.env :as env] 4 | [shadow.cljs.devtools.client.shared :as cljs-shared] 5 | [shadow.remote.runtime.cljs.js-builtins] 6 | )) 7 | 8 | ;; FIXME: protocolize the 3 fns 9 | 10 | (defn start 11 | ([runtime] 12 | (start js/WebSocket runtime)) 13 | ([ws-impl runtime] 14 | (let [ws-url (env/get-ws-relay-url) 15 | socket (ws-impl. ws-url)] 16 | 17 | (set! socket -onmessage 18 | (fn [e] 19 | (cljs-shared/remote-msg runtime (.-data e)))) 20 | 21 | (set! socket -onopen 22 | (fn [e] 23 | (cljs-shared/remote-open runtime e))) 24 | 25 | (set! socket -onclose 26 | (fn [e] 27 | (cljs-shared/remote-close runtime e ws-url))) 28 | 29 | (set! socket -onerror 30 | (fn [e] 31 | ;; followed by close 32 | (cljs-shared/remote-error runtime e))) 33 | 34 | socket))) 35 | 36 | (defn send [socket msg] 37 | (.send socket msg)) 38 | 39 | (defn stop [socket] 40 | ;; chrome sometimes gets stuck websockets when waking up from sleep 41 | ;; at least on my macbook macos chrome, works fine in windows 42 | ;; these sockets don't receive messages or send them 43 | ;; and will eventually time out after a minute or so 44 | ;; at which point we no longer care about close messages as a new one will 45 | ;; be active and we don't want to a late onclose message to disconnect that one. 46 | 47 | ;; firefox also has the stuck socket but that is closed pretty much immediately on wake 48 | ;; it still shows an error "was interrupted while loading page" after a bit 49 | ;; can't seem to get rid of that one but it is from the socket we no longer care about anyways 50 | (set! (.-onopen socket) nil) 51 | (set! (.-onclose socket) nil) 52 | (set! (.-onmessage socket) nil) 53 | (set! (.-onerror socket) nil) 54 | (.close socket)) 55 | 56 | -------------------------------------------------------------------------------- /src/main/shadow/cljs/devtools/plugin_manager.clj: -------------------------------------------------------------------------------- 1 | (ns shadow.cljs.devtools.plugin-manager) 2 | 3 | (defn start []) 4 | 5 | (defn stop [svc]) -------------------------------------------------------------------------------- /src/main/shadow/cljs/devtools/server/cli_check.clj: -------------------------------------------------------------------------------- 1 | (ns shadow.cljs.devtools.server.cli-check 2 | (:import [java.lang ProcessHandle])) 3 | 4 | (defn attach [ppid] 5 | (let [pho (ProcessHandle/of (Long/valueOf ppid))] 6 | (when (.isPresent pho) 7 | (let [ph (.get pho)] 8 | (-> (.onExit ph) 9 | (.thenRun (fn [] 10 | ;; this will trigger the regular shutdown hooks 11 | (System/exit 0))) 12 | ))))) 13 | -------------------------------------------------------------------------------- /src/main/shadow/cljs/devtools/server/dev_http/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thheller/shadow-cljs/efd77b59a1f89a6c877e8471c26f127095271ec5/src/main/shadow/cljs/devtools/server/dev_http/favicon.ico -------------------------------------------------------------------------------- /src/main/shadow/cljs/devtools/server/env.clj: -------------------------------------------------------------------------------- 1 | (ns shadow.cljs.devtools.server.env 2 | (:require [clojure.java.io :as io])) 3 | 4 | (def dependencies-modified-ref (atom false)) 5 | 6 | (defn jar-version [] 7 | (when-let [rc (io/resource "META-INF/leiningen/thheller/shadow-cljs/project.clj")] 8 | (-> (slurp rc) 9 | (read-string) 10 | ;; (defproject thheller/shadow-cljs "2.0.113" 11 | (nth 2) 12 | ))) 13 | 14 | (defn restart-required? [] 15 | @dependencies-modified-ref) 16 | -------------------------------------------------------------------------------- /src/main/shadow/cljs/devtools/server/nrepl04.clj: -------------------------------------------------------------------------------- 1 | (ns shadow.cljs.devtools.server.nrepl04 2 | "just delegates to the default nrepl impl, no longer supporting old versions" 3 | (:require 4 | [nrepl.middleware :as middleware] 5 | [shadow.cljs.devtools.server.nrepl :as nrepl])) 6 | 7 | (def middleware nrepl/middleware) 8 | 9 | (middleware/set-descriptor! 10 | #'middleware 11 | {:requires #{"clone"} 12 | :expects #{#'cider.piggieback/wrap-cljs-repl}}) 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /src/main/shadow/cljs/devtools/server/ns_explorer.clj: -------------------------------------------------------------------------------- 1 | (ns shadow.cljs.devtools.server.ns-explorer 2 | "explorer for cljs analyzer data of the current classpath 3 | not tied to any build or REPL" 4 | (:require 5 | [clojure.core.async :as async :refer (!!)] 6 | [shadow.cljs.devtools.server.util :as util] 7 | [shadow.cljs.devtools.server.ns-explorer.impl :as impl] 8 | [shadow.cljs.devtools.server.supervisor :as super] 9 | [shadow.cljs.devtools.server.worker :as worker] 10 | )) 11 | 12 | (defn service? [svc] 13 | (and (map? svc) 14 | (::service svc))) 15 | 16 | (defn get-ns-data [{:keys [control] :as svc} ns-sym] 17 | (let [reply-to (async/chan 1)] 18 | (when (>!! control {:op ::impl/get-ns-data :ns-sym ns-sym :reply-to reply-to}) 19 | ( (cljs/init-state) 26 | (assoc :output-dir output-dir 27 | :asset-path asset-path) 28 | (cljs/find-resources-in-classpath) 29 | (repl/prepare)) 30 | 31 | {:keys [repl-sources]} 32 | repl-state] 33 | 34 | ;; load in goog/base.js 35 | (.eval se @(get-in state [:sources "goog/base.js" :input])) 36 | 37 | ;; setup repl 38 | (doseq [src repl-sources] 39 | (let [js (get-in state [:sources src :output])] 40 | (.eval se js))) 41 | 42 | ;; (prn (.invokeMethod ^Invocable se (.eval se "cljs.core") "pr_str" (into-array ["foo" "bar"]))) 43 | )) 44 | -------------------------------------------------------------------------------- /src/main/shadow/cljs/npm/util.cljs: -------------------------------------------------------------------------------- 1 | (ns shadow.cljs.npm.util 2 | (:require 3 | ["child_process" :as cp] 4 | ["fs" :as fs])) 5 | 6 | (defn slurp [file] 7 | (-> (fs/readFileSync file) 8 | (.toString))) 9 | 10 | (defn reduce-> [init reduce-fn coll] 11 | (reduce reduce-fn init coll)) 12 | 13 | (defn conj-set [x y] 14 | (if (nil? x) 15 | #{y} 16 | (conj x y))) 17 | 18 | (defn kill-proc [^js proc] 19 | ;; the java process should now always exit cleanly when the node process is killed 20 | ;; so we just kill the node process to let the jvm shutdown cleanly 21 | (.kill proc) 22 | #_(case js/process.platform 23 | "win32" 24 | (cp/spawnSync "taskkill" #js ["/pid" (.-pid proc) "/f" #_"/t"]) 25 | 26 | (.kill proc) 27 | )) -------------------------------------------------------------------------------- /src/main/shadow/cljs/silence_default_loggers.clj: -------------------------------------------------------------------------------- 1 | (ns shadow.cljs.silence-default-loggers 2 | (:import [java.util.logging Logger Level])) 3 | 4 | ;; xnio logs an annoying version INFO on startup we are not interested in 5 | 6 | (-> (Logger/getLogger "") 7 | (.setLevel Level/WARNING)) 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/main/shadow/cljs/ui/db/builds.cljs: -------------------------------------------------------------------------------- 1 | (ns shadow.cljs.ui.db.builds 2 | (:require 3 | [shadow.grove.events :as ev] 4 | [shadow.cljs :as-alias m] 5 | [shadow.cljs.ui.db.relay-ws :as relay-ws])) 6 | 7 | (defn forward-to-ws! 8 | {::ev/handle 9 | [::m/build-watch-compile! 10 | ::m/build-watch-stop! 11 | ::m/build-watch-start! 12 | ::m/build-compile! 13 | ::m/build-release! 14 | ::m/build-release-debug!]} 15 | [env {:keys [e build-id]}] 16 | (ev/queue-fx env 17 | :relay-send 18 | [{:op e 19 | :to 1 ;; FIXME: don't hardcode CLJ runtime id 20 | ::m/build-id build-id}])) 21 | 22 | (defn active-builds [env] 23 | (->> (::m/build env) 24 | (vals) 25 | (filter ::m/build-worker-active) 26 | (sort-by ::m/build-id) 27 | (map ::m/build-id) 28 | (into []))) 29 | 30 | (defn relay-sub-msg 31 | {::ev/handle ::m/sub-msg} 32 | [env {::m/keys [topic] :as msg}] 33 | ;; FIXME: this is dead right? superseded by sync-db? 34 | (do (js/console.warn "unhandled sub msg" msg) 35 | env)) -------------------------------------------------------------------------------- /src/main/shadow/cljs/ui/main.css: -------------------------------------------------------------------------------- 1 | body { 2 | font-size: 14px; 3 | font-family:ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji"; 4 | 5 | margin: 0; 6 | padding: 0; 7 | -fx-font-smoothing-type: gray; 8 | } -------------------------------------------------------------------------------- /src/main/shadow/core_ext.clj: -------------------------------------------------------------------------------- 1 | (ns shadow.core-ext) 2 | 3 | (defn safe-pr-str 4 | "cider globally sets *print-length* for the nrepl-session which messes with pr-str when used to print cache or other files" 5 | [x] 6 | (binding [*print-length* nil 7 | *print-level* nil 8 | *print-namespace-maps* nil 9 | *print-meta* nil] 10 | (pr-str x) 11 | )) 12 | -------------------------------------------------------------------------------- /src/main/shadow/debug.cljs: -------------------------------------------------------------------------------- 1 | (ns shadow.debug 2 | (:require-macros [shadow.debug])) 3 | 4 | (defn tap-> [obj opts] 5 | (tap> [:shadow.remote/wrap obj opts]) 6 | obj) -------------------------------------------------------------------------------- /src/main/shadow/expo.cljs: -------------------------------------------------------------------------------- 1 | (ns shadow.expo 2 | (:require 3 | ["expo" :as expo] 4 | ["create-react-class" :as crc])) 5 | 6 | (defonce root-ref (atom nil)) 7 | (defonce root-component-ref (atom nil)) 8 | 9 | (defn render-root [root] 10 | (let [first-call? (nil? @root-ref)] 11 | (reset! root-ref root) 12 | 13 | (if-not first-call? 14 | (when-let [root @root-component-ref] 15 | (.forceUpdate ^js root)) 16 | (let [Root 17 | (crc 18 | #js {:componentDidMount 19 | (fn [] 20 | (this-as this 21 | (reset! root-component-ref this))) 22 | :componentWillUnmount 23 | (fn [] 24 | (reset! root-component-ref nil)) 25 | :render 26 | (fn [] 27 | (let [body @root-ref] 28 | (if (fn? body) 29 | (body) 30 | body)))})] 31 | 32 | (expo/registerRootComponent Root))))) 33 | 34 | 35 | -------------------------------------------------------------------------------- /src/main/shadow/expo/keep_awake.cljs: -------------------------------------------------------------------------------- 1 | (ns ^:dev/once shadow.expo.keep-awake 2 | (:require ["expo-keep-awake" :refer [activateKeepAwake]])) 3 | 4 | (activateKeepAwake) -------------------------------------------------------------------------------- /src/main/shadow/expo/keep_awake_async.cljs: -------------------------------------------------------------------------------- 1 | (ns ^:dev/once shadow.expo.keep-awake-async 2 | (:require ["expo-keep-awake" :refer [activateKeepAwakeAsync]])) 3 | 4 | (activateKeepAwakeAsync) 5 | -------------------------------------------------------------------------------- /src/main/shadow/insight.clj: -------------------------------------------------------------------------------- 1 | (ns shadow.insight) 2 | 3 | 4 | (defn main []) -------------------------------------------------------------------------------- /src/main/shadow/js/babel.js: -------------------------------------------------------------------------------- 1 | goog.provide("shadow.js.babel"); 2 | 3 | /** 4 | * @dict 5 | */ 6 | shadow.js.babel = {}; 7 | 8 | shadow.js.babel["interopRequireDefault"] = function (obj) { 9 | return obj && obj.__esModule ? obj : { 10 | "default": obj 11 | }; 12 | }; 13 | 14 | shadow.js.babel["interopRequireWildcard"] = function (obj) { 15 | if (obj && obj.__esModule) { 16 | return obj; 17 | } else { 18 | var newObj = {}; 19 | 20 | if (obj != null) { 21 | for (var key in obj) { 22 | if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; 23 | } 24 | } 25 | 26 | newObj["default"] = obj; 27 | return newObj; 28 | } 29 | }; 30 | 31 | goog.exportSymbol("shadow.js.babel", shadow.js.babel); -------------------------------------------------------------------------------- /src/main/shadow/json.cljs: -------------------------------------------------------------------------------- 1 | (ns shadow.json 2 | (:require [goog.object :as gobj])) 3 | 4 | (defn to-clj 5 | "simplified js->clj for JSON data, :key-fn default to keyword" 6 | ([x] (to-clj x {})) 7 | ([x opts] 8 | (cond 9 | (nil? x) 10 | x 11 | 12 | (number? x) 13 | x 14 | 15 | (string? x) 16 | x 17 | 18 | (boolean? x) 19 | x 20 | 21 | (array? x) 22 | (into [] (map #(to-clj % opts)) (array-seq x)) 23 | 24 | :else ;; object 25 | (let [key-fn (get opts :key-fn keyword)] 26 | (->> (gobj/getKeys x) 27 | (reduce 28 | (fn [result key] 29 | (let [value (gobj/get x key)] 30 | (assoc! result 31 | (if (string? key) 32 | (key-fn key) 33 | (to-clj key opts)) 34 | (to-clj value opts)))) 35 | (transient {})) 36 | (persistent!)))))) 37 | 38 | (defn read-str [str opts] 39 | (to-clj (js/JSON.parse str) opts)) 40 | 41 | (defn write-str [obj] 42 | (-> (clj->js obj) 43 | (js/JSON.stringify))) -------------------------------------------------------------------------------- /src/main/shadow/lazy.cljs: -------------------------------------------------------------------------------- 1 | (ns shadow.lazy 2 | (:require-macros [shadow.lazy]) 3 | (:require 4 | [goog.async.Deferred] 5 | [goog.object :as gobj] 6 | [shadow.loader :as l])) 7 | 8 | 9 | (defprotocol ILoadable 10 | (ready? [x])) 11 | 12 | (deftype Loadable [modules deref-fn] 13 | ILoadable 14 | (ready? [this] 15 | (every? l/loaded? modules)) 16 | 17 | IDeref 18 | (-deref [this] 19 | (when-not (ready? this) 20 | (throw (ex-info "loadable not ready yet" {:modules modules}))) 21 | 22 | (deref-fn))) 23 | 24 | (defn loadable [thing]) ;; macro 25 | 26 | ;; FIXME: maybe just replace all the goog.module.ModuleManager stuff 27 | ;; the API is just weird, can't control retries 28 | ;; why does it retry when all code is loaded but the eval failed? 29 | ;; FIXME: maybe don't expose the Thenable API, just take explicit args 30 | ;; would make it easier to port this to Clojure 31 | (defn load 32 | ([^Loadable the-loadable] 33 | {:pre [(instance? Loadable the-loadable)]} 34 | (let [all-mods (.-modules the-loadable) 35 | 36 | ;; FIXME: extra path if only loading one? 37 | loading-map 38 | (l/load-multiple (into-array (map name) all-mods)) 39 | 40 | combined 41 | (js/goog.async.Deferred.) 42 | 43 | callback-fn 44 | (.-deref-fn the-loadable) 45 | 46 | err-fn 47 | (fn [err] 48 | (.errback combined err)) 49 | 50 | success-fn 51 | (fn [] 52 | (when (ready? the-loadable) 53 | (.callback combined (callback-fn))))] 54 | 55 | (doseq [mod all-mods] 56 | (let [^js mod-deferred (gobj/get loading-map (name mod))] 57 | (.addCallbacks mod-deferred success-fn err-fn))) 58 | 59 | combined)) 60 | ([the-loadable call-fn] 61 | (-> (load the-loadable) 62 | (.then call-fn))) 63 | ([the-loadable call-fn err-fn] 64 | (-> (load the-loadable) 65 | (.then call-fn err-fn)))) 66 | -------------------------------------------------------------------------------- /src/main/shadow/remote/relay/api.cljc: -------------------------------------------------------------------------------- 1 | (ns shadow.remote.relay.api) 2 | 3 | (defprotocol IRelayClient 4 | ;; returns extra channel that will never receive anything 5 | ;; only closes when the connection terminates 6 | ;; closing from-client will cause the loop shutdown 7 | ;; to-client will be closed if sending to it failed 8 | ;; which will also terminate the connection 9 | ;; connection info is a map of data, which may provide additional details 10 | ;; that the client cannot directly provide itself (eg. network details) 11 | ;; remote connections should include {:remote true} 12 | (connect [relay from-client to-client connection-info])) -------------------------------------------------------------------------------- /src/main/shadow/remote/runtime/LimitWriter.java: -------------------------------------------------------------------------------- 1 | package shadow.remote.runtime; 2 | 3 | import java.io.IOException; 4 | import java.io.StringWriter; 5 | import java.io.Writer; 6 | 7 | public class LimitWriter extends Writer { 8 | private final int limit; 9 | private final StringWriter sw; 10 | 11 | public LimitWriter(int limit) { 12 | this.limit = limit; 13 | this.sw = new StringWriter(limit); 14 | } 15 | 16 | @Override 17 | public void write(char[] cbuf, int off, int len) throws IOException { 18 | sw.write(cbuf, off, len); 19 | 20 | if (sw.getBuffer().length() > this.limit) { 21 | throw new LimitReachedException(); 22 | } 23 | } 24 | 25 | public String getString() { 26 | String res = this.sw.getBuffer().toString(); 27 | 28 | if (res.length() > limit) { 29 | return res.substring(0, limit); 30 | } else { 31 | return res; 32 | } 33 | } 34 | 35 | @Override 36 | public void flush() throws IOException { 37 | } 38 | 39 | @Override 40 | public void close() throws IOException { 41 | } 42 | 43 | public static class LimitReachedException extends IOException { 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/main/shadow/remote/runtime/api.cljc: -------------------------------------------------------------------------------- 1 | (ns shadow.remote.runtime.api) 2 | 3 | (defprotocol IRuntime 4 | (relay-msg [runtime msg]) 5 | (add-extension [runtime key spec]) 6 | (del-extension [runtime key])) 7 | 8 | (defprotocol Inspectable 9 | :extend-via-metadata true 10 | (describe [thing opts] "returns a map descriptor that tells system how to handle things further")) 11 | 12 | #?(:cljs 13 | (do (defprotocol IEvalCLJS 14 | (-cljs-eval [runtime input callback])) 15 | 16 | (defprotocol IEvalJS 17 | (-js-eval [runtime code success fail])) 18 | 19 | (defn cljs-eval 20 | [^IEvalCLJS runtime {:keys [code ns] :as input} callback] 21 | (when-not (and (string? code) 22 | (simple-symbol? ns)) 23 | (throw (ex-info "invalid cljs-eval input" {:input input}))) 24 | (-cljs-eval runtime input callback)) 25 | 26 | (defn js-eval 27 | [^IEvalJS runtime code success fail] 28 | {:pre [(string? code)]} 29 | (-js-eval runtime code success fail)))) 30 | 31 | (comment 32 | ;; nav feels limited by being in metadata 33 | ;; and coupled to the result of datafy 34 | ;; also has no notion of async built-in which could be a problem for CLJS 35 | 36 | ;; will still be used as the default descriptor impl 37 | 38 | ;; I would like to transmit metadata to the UI but by nav/datafy potentially 39 | ;; being in metadata I have to filter it first, which seems like a bad default 40 | 41 | ;; returns one-line text summary of something. default to edn preview, could be custom 42 | {::preview-self (fn [opts]) 43 | ;; returns map description. similar to :summary view right now 44 | ::summary (fn [opts]) => {:entries 123 :obj-type "cljs.core/PersistentArrayMap"} 45 | ::preview-entry (fn [idx opts]) 46 | ;; similar to nav, but navs by idx 47 | ::nav (fn [idx opts callback])}) 48 | 49 | -------------------------------------------------------------------------------- /src/main/shadow/remote/runtime/cljs/browser.cljs: -------------------------------------------------------------------------------- 1 | (ns shadow.remote.runtime.cljs.browser) 2 | 3 | ;; keeping this for old inspect users 4 | ;; migrated everything to the shadow-cljs client namespaces 5 | -------------------------------------------------------------------------------- /src/main/shadow/remote/runtime/cljs/js_builtins.cljs: -------------------------------------------------------------------------------- 1 | (ns shadow.remote.runtime.cljs.js-builtins 2 | (:require 3 | [goog.object :as gobj] 4 | [clojure.core.protocols :as p])) 5 | 6 | (extend-protocol p/Datafiable 7 | ;; FIXME: this is kind of a bad idea 8 | ;; can't do this for all objects, since none of the CLJS types implement this 9 | ;; protocol either. the protocol dispatch will end up using object 10 | ;; FIXME: this could detect CLJS types to some extent 11 | ;; or should it just implement the protocols for the types? 12 | object 13 | (datafy [o] 14 | (if-not (identical? (.-__proto__ o) js/Object.prototype) 15 | o 16 | (with-meta 17 | (->> (gobj/getKeys o) 18 | (reduce 19 | (fn [m key] 20 | (assoc! m key (gobj/get o key))) 21 | (transient {})) 22 | (persistent!)) 23 | 24 | {`p/nav (fn [coll k v] 25 | (gobj/get o k))}))) 26 | 27 | array 28 | (datafy [o] 29 | (vec o)) 30 | 31 | js/Error 32 | (datafy [e] 33 | (let [data (ex-data e) 34 | file (.-fileName e) 35 | line (.-lineNumber e) 36 | column (.-columnNumber e)] 37 | (-> {:message (.-message e) 38 | :name (.-name e) 39 | :stack (.-stack e)} 40 | (cond-> 41 | (some? data) 42 | (assoc :data data) 43 | 44 | file 45 | (assoc :file file) 46 | 47 | line 48 | (assoc :line line) 49 | 50 | column 51 | (assoc :column column) 52 | ))))) 53 | -------------------------------------------------------------------------------- /src/main/shadow/remote/runtime/cljs/node.cljs: -------------------------------------------------------------------------------- 1 | (ns shadow.remote.runtime.cljs.node) 2 | 3 | ;; keeping this for old inspect users 4 | ;; migrated everything to the shadow-cljs client namespaces 5 | -------------------------------------------------------------------------------- /src/main/shadow/remote/runtime/explore_support.clj: -------------------------------------------------------------------------------- 1 | (ns shadow.remote.runtime.explore-support 2 | (:require 3 | [shadow.debug :refer (?> ?-> ?->>)] 4 | [shadow.remote.runtime.api :as p] 5 | [shadow.remote.runtime.shared :as shared] 6 | [shadow.remote.runtime.obj-support :as obj-support] 7 | )) 8 | 9 | (defn namespaces [{:keys [runtime] :as svc} msg] 10 | (shared/reply runtime msg 11 | {:op :explore/namespaces-result 12 | :namespaces (->> (all-ns) 13 | (map #(.getName ^clojure.lang.Namespace %)) 14 | (sort-by name) 15 | (vec))})) 16 | 17 | (defn namespace-vars [{:keys [runtime] :as svc} {:keys [ns] :as msg}] 18 | (shared/reply runtime msg 19 | {:op :explore/namespace-vars-result 20 | :vars (->> (ns-publics ns) 21 | (keys) 22 | (sort-by name) 23 | (mapv (fn [sym] 24 | (symbol (name ns) (name sym)))))})) 25 | 26 | (defn describe-ns [{:keys [runtime] :as svc} {:keys [ns] :as msg}] 27 | (shared/reply runtime msg 28 | {:op :explore/describe-ns-result 29 | :description (meta (find-ns ns))})) 30 | 31 | (defn describe-var [{:keys [runtime] :as svc} {:keys [var] :as msg}] 32 | (let [var (find-var var) 33 | m (meta var)] 34 | 35 | (shared/reply runtime msg 36 | {:op :explore/describe-var-result 37 | :description (dissoc m :ns :name)}))) 38 | 39 | (defn start [runtime obj-support] 40 | (let [svc 41 | {:runtime runtime 42 | :obj-support obj-support}] 43 | 44 | (p/add-extension runtime 45 | ::ext 46 | {:ops 47 | {:explore/namespaces #(namespaces svc %) 48 | :explore/namespace-vars #(namespace-vars svc %) 49 | :explore/describe-var #(describe-var svc %) 50 | :explore/describe-ns #(describe-ns svc %)}}) 51 | 52 | svc)) 53 | 54 | (defn stop [{:keys [runtime] :as svc}] 55 | (p/del-extension runtime ::ext)) 56 | 57 | 58 | -------------------------------------------------------------------------------- /src/main/shadow/remote/runtime/writer.clj: -------------------------------------------------------------------------------- 1 | (ns shadow.remote.runtime.writer 2 | (:import [shadow.remote.runtime LimitWriter LimitWriter$LimitReachedException])) 3 | 4 | (defn pr-str-limit [obj limit] 5 | (let [lw (LimitWriter. limit)] 6 | (try 7 | (binding [*out* lw] 8 | (pr obj)) 9 | (str "0," (.getString lw)) 10 | (catch LimitWriter$LimitReachedException e 11 | (str "1," (.getString lw)))))) 12 | 13 | (defn limit-writer [limit] 14 | (LimitWriter. limit)) 15 | 16 | (defn get-string [^LimitWriter lw] 17 | (.getString lw)) 18 | 19 | (comment 20 | (pr-str-limit {:hello (range 10)} 20)) 21 | -------------------------------------------------------------------------------- /src/main/shadow/remote/runtime/writer.cljs: -------------------------------------------------------------------------------- 1 | (ns shadow.remote.runtime.writer 2 | (:import [goog.string StringBuffer])) 3 | 4 | (deftype LimitWriter [^StringBuffer sb limit] 5 | Object 6 | (getString [this] 7 | (.toString sb)) 8 | 9 | IWriter 10 | (-write [_ s] 11 | (.append sb s) 12 | (when (>= (.getLength sb) limit) 13 | (throw (ex-info (str "The limit of " limit " bytes was reached while printing.") {:tag ::limit-reached :limit limit})))) 14 | (-flush [_] nil)) 15 | 16 | (defn pr-str-limit [obj limit] 17 | (let [sb (StringBuffer.) 18 | writer (LimitWriter. sb limit)] 19 | (try 20 | (pr-writer obj writer (pr-opts)) 21 | (str "0," (.toString sb)) 22 | (catch :default e 23 | (if-not (keyword-identical? ::limit-reached (:tag (ex-data e))) 24 | (throw e) 25 | (str "1," 26 | (let [s (.toString sb)] 27 | (if (> (.-length s) limit) 28 | (subs s 0 limit) 29 | s)))))))) 30 | 31 | (defn limit-writer [limit] 32 | (let [sb (StringBuffer.)] 33 | (LimitWriter. sb limit))) 34 | 35 | (defn get-string [^LimitWriter lw] 36 | (.getString lw)) 37 | 38 | (comment 39 | (pr-str-limit {:hello (range 10)} 20)) 40 | -------------------------------------------------------------------------------- /src/main/shadow/repl.clj: -------------------------------------------------------------------------------- 1 | (ns shadow.repl) 2 | -------------------------------------------------------------------------------- /src/main/shadow/resource.cljs: -------------------------------------------------------------------------------- 1 | (ns shadow.resource 2 | (:require-macros [shadow.resource])) 3 | -------------------------------------------------------------------------------- /src/main/shadow/test/browser.cljs: -------------------------------------------------------------------------------- 1 | (ns shadow.test.browser 2 | "generic browser test runner" 3 | {:dev/always true} 4 | (:require 5 | [shadow.test :as st] 6 | [shadow.test.env :as env] 7 | [shadow.dom :as dom] 8 | [cljs-test-display.core :as ctd])) 9 | 10 | (defn start [] 11 | (-> (env/get-test-data) 12 | (env/reset-test-data!)) 13 | 14 | (st/run-all-tests (ctd/init! "test-root"))) 15 | 16 | (defn stop [done] 17 | ;; FIXME: determine if async tests are still pending 18 | (done)) 19 | 20 | ;; not sure we need to do something once? 21 | (defn ^:export init [] 22 | (dom/append [:div#test-root]) 23 | (start)) 24 | -------------------------------------------------------------------------------- /src/main/shadow/test/env.clj: -------------------------------------------------------------------------------- 1 | (ns shadow.test.env 2 | (:require 3 | [cljs.env :as env] 4 | [cljs.analyzer :as ana] 5 | )) 6 | 7 | (defmacro get-test-data [] 8 | (reduce 9 | (fn [m {:keys [name defs] :as the-ns}] 10 | (let [{:syms [cljs-test-once-fixtures cljs-test-each-fixtures]} 11 | defs 12 | 13 | vars 14 | (->> (vals defs) 15 | (filter :test) 16 | (sort-by #(-> % :meta :line)) 17 | (map (fn [{:keys [name]}] 18 | (list 'var name))) 19 | (into [])) 20 | 21 | ns-info 22 | (-> {} 23 | (cond-> 24 | cljs-test-once-fixtures 25 | (assoc-in [:fixtures :once] (:name cljs-test-once-fixtures)) 26 | 27 | cljs-test-each-fixtures 28 | (assoc-in [:fixtures :each] (:name cljs-test-each-fixtures)) 29 | 30 | (seq vars) 31 | (assoc :vars vars)))] 32 | 33 | 34 | (if-not (seq ns-info) 35 | m 36 | (assoc m `(quote ~name) ns-info)))) 37 | {} 38 | (vals (::ana/namespaces @env/*compiler*)))) 39 | -------------------------------------------------------------------------------- /src/main/shadow/test/env.cljs: -------------------------------------------------------------------------------- 1 | (ns shadow.test.env 2 | (:require-macros [shadow.test.env])) 3 | 4 | (goog-define UI-DRIVEN false) 5 | 6 | ;; this should be how cljs.test works out of the box IMHO 7 | ;; all those macros don't compose and make writing testing utilities painful 8 | ;; (eg. you have to recompile the namespace containing the macro to pick up new tests) 9 | ;; only the macros were replaced, the functionality remains unchanged 10 | (defonce tests-ref (atom {:namespaces {}})) 11 | 12 | (defn reset-test-data! [test-data] 13 | (swap! tests-ref assoc :namespaces test-data)) 14 | 15 | (defn get-tests [] 16 | (get @tests-ref :namespaces)) 17 | 18 | (defn get-test-vars [] 19 | (for [[ns ns-info] (get-tests) 20 | var (:vars ns-info)] 21 | var)) 22 | 23 | (defn get-test-ns-info [ns] 24 | {:pre [(symbol? ns)]} 25 | (get-in @tests-ref [:namespaces ns])) 26 | 27 | (defn get-test-namespaces 28 | "returns all the registered test namespaces and symbols 29 | use (get-test-ns-info the-sym) to get the details" 30 | [] 31 | (-> @tests-ref (:namespaces) (keys))) 32 | 33 | (defn get-test-count [] 34 | (->> (for [{:keys [vars] :as test-ns} (-> @tests-ref (:namespaces) (vals))] 35 | (count vars)) 36 | (reduce + 0))) -------------------------------------------------------------------------------- /src/main/shadow/test/repl.cljc: -------------------------------------------------------------------------------- 1 | (ns shadow.test.repl 2 | (:require 3 | [clojure.test :as ct :refer (deftest is)])) 4 | 5 | (defonce last-test-ref (atom nil)) 6 | 7 | ;; ~selection - the current selection 8 | ;; ~selected-form - the currently selected form if the selection is a single valid form 9 | ;; ~file-name - the name of the current file 10 | ;; ~file-path - the full path of the current file 11 | ;; ~file-namespace - the namespace of the current file, if any, as a symbol 12 | ;; ~form-before-caret - the text of the form immediately before the caret 13 | ;; ~top-level-form - the text of the top-level form under the caret 14 | ;; ~current-var - the FQN of the current var under the caret 15 | ;; ~current-test-var - the FQN of the current var under the caret, if it represents a test 16 | ;l ~current-function - the FQN of the current var under the caret, if it represents a function 17 | 18 | (defn run-test [{:keys [test-var] :as info}] 19 | (reset! last-test-ref test-var) 20 | 21 | (test-var)) 22 | 23 | (defn re-run [] 24 | (let [test-var @last-test-ref] 25 | (if-not test-var 26 | (println "No test-var selected.") 27 | (ct/test-var test-var) 28 | ))) 29 | 30 | (deftest dummy-test 31 | (is (= 1 2))) 32 | -------------------------------------------------------------------------------- /src/main/shadow/test/workspaces.cljs: -------------------------------------------------------------------------------- 1 | (ns shadow.test.workspaces 2 | (:require 3 | [nubank.workspaces.core :as ws])) 4 | 5 | (defn start []) 6 | 7 | (defn stop [done] 8 | (done)) 9 | 10 | (defn ^:export init [] 11 | ;; FIXME: connect websocket that acts as a unload signal 12 | ;; when page is not open by anyone the build doesn't need to be running 13 | 14 | (ws/mount)) 15 | -------------------------------------------------------------------------------- /src/main/shadow/txt/repl-help.txt: -------------------------------------------------------------------------------- 1 | shadow-cljs - CLJ REPL 2 | 3 | (shadow/start-worker :foo) - Starts a dev process for build :foo 4 | (shadow/repl :foo) - Switches the current REPL to that of :foo 5 | (shadow/stop-worker :foo) - Stop the dev process 6 | 7 | (shadow/dev :foo) - start build, connects repl, stops on :repl/quit 8 | (shadow/once :foo) - Compiles a dev build once 9 | (shadow/release :foo) - Create a release build for :foo 10 | 11 | (shadow/node-repl) - launches a node process and connects to a CLJS REPL 12 | -------------------------------------------------------------------------------- /src/main/shadow/user.clj: -------------------------------------------------------------------------------- 1 | (ns shadow.user 2 | (:require 3 | [clojure.repl :refer (source apropos dir pst doc find-doc)] 4 | [clojure.java.javadoc :refer (javadoc)] 5 | [clojure.pprint :refer (pp pprint)] 6 | [shadow.cljs.devtools.api :as shadow :refer (help)])) 7 | -------------------------------------------------------------------------------- /src/repl/Test.java: -------------------------------------------------------------------------------- 1 | import java.io.FileOutputStream; 2 | import java.io.IOException; 3 | 4 | public class Test { 5 | public static void main(String[] args) throws IOException { 6 | for (; ; ) { 7 | int c = System.in.read(); 8 | if (c == -1) 9 | break; 10 | System.out.print(c); 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/repl/app/page.cljs: -------------------------------------------------------------------------------- 1 | (ns app.page 2 | (:require ["react-dom" :refer (render)])) 3 | -------------------------------------------------------------------------------- /src/repl/app/shared.cljs: -------------------------------------------------------------------------------- 1 | (ns app.shared 2 | (:require ["react" :as react])) 3 | -------------------------------------------------------------------------------- /src/repl/bar.js: -------------------------------------------------------------------------------- 1 | require("./"); 2 | 3 | module.exports = "bar"; -------------------------------------------------------------------------------- /src/repl/code_split/a.cljs: -------------------------------------------------------------------------------- 1 | (ns code-split.a 2 | (:require [shadow.loader :as loader])) 3 | 4 | (js/console.log :foo :X ::a) 5 | 6 | (defn ^:export foo [x] 7 | (str "foo" x)) 8 | 9 | (defn test-fn [] 10 | (-> (loader/load "c") 11 | (.then #(code-split.c/in-c "from-a")))) 12 | 13 | (js/window.setTimeout test-fn 100) 14 | -------------------------------------------------------------------------------- /src/repl/code_split/b.cljs: -------------------------------------------------------------------------------- 1 | (ns code-split.b 2 | (:require [code-split.a :as a])) 3 | 4 | (js/console.log :foo :X ::a/a ::b 1 "foo" (a/foo 1)) -------------------------------------------------------------------------------- /src/repl/code_split/c.cljs: -------------------------------------------------------------------------------- 1 | (ns code-split.c) 2 | 3 | (js/console.log :foo) 4 | 5 | (defn in-c [x] 6 | (js/console.log "in-c" x)) -------------------------------------------------------------------------------- /src/repl/code_split/externs.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * @const 4 | */ 5 | var $; 6 | 7 | $.module = {}; 8 | $.module.exports; 9 | 10 | /** @const */ 11 | var process; 12 | -------------------------------------------------------------------------------- /src/repl/demo/http.clj: -------------------------------------------------------------------------------- 1 | (ns demo.http) 2 | 3 | (defn handle [req] 4 | {:status 200 5 | :body "hello world"}) 6 | -------------------------------------------------------------------------------- /src/repl/demo/test_dummy.cljs: -------------------------------------------------------------------------------- 1 | (ns demo.test-dummy 2 | (:require [cljs.test :as ct :refer (deftest is)] 3 | ["react" :as react])) 4 | 5 | (ct/use-fixtures :once 6 | {:before 7 | (fn [] 8 | (println "once before")) 9 | :after 10 | (fn [] 11 | (println "once after"))}) 12 | 13 | (ct/use-fixtures :each 14 | {:before 15 | (fn [] 16 | (println "each before")) 17 | 18 | :after 19 | (fn [] 20 | (println "each after"))}) 21 | 22 | (deftest a-failing-test 23 | (is (= 1 2))) 24 | 25 | (deftest a-passing-test 26 | (is (= 1 1))) 27 | -------------------------------------------------------------------------------- /src/repl/index.js: -------------------------------------------------------------------------------- 1 | module.exports = "index"; -------------------------------------------------------------------------------- /src/repl/react.externs.js: -------------------------------------------------------------------------------- 1 | // https://github.com/roman01la/scrum-ssr-example/blob/react/externs/react.js#L1827-L1840 2 | 3 | /** 4 | * React event system creates plugins and event properties dynamically. 5 | * These externs are needed when consuming React as a JavaScript module 6 | * in light of new ClojureScript compiler additions (as of version 1.9.456). 7 | * See the following link for an example. 8 | * https://github.com/facebook/react/blob/c7129c/src/renderers/dom/shared/eventPlugins/SimpleEventPlugin.js#L43 9 | */ 10 | var ResponderEventPlugin; 11 | var SimpleEventPlugin; 12 | var TapEventPlugin; 13 | var EnterLeaveEventPlugin; 14 | var ChangeEventPlugin; 15 | var SelectEventPlugin; 16 | var BeforeInputEventPlugin; -------------------------------------------------------------------------------- /src/repl/shadow/build/js_inspector_test.clj: -------------------------------------------------------------------------------- 1 | (ns shadow.build.js-inspector-test 2 | (:require 3 | [clojure.test :as ct :refer (deftest is)] 4 | [clojure.java.io :as io] 5 | [shadow.build.data :as data] 6 | [shadow.build.closure :as closure] 7 | [shadow.build.classpath :as classpath]) 8 | (:import 9 | [shadow.build.closure JsInspector])) 10 | 11 | 12 | (deftest dummy-inspect 13 | 14 | (let [resource-name 15 | "goog/events/events.js" 16 | 17 | source 18 | (slurp (io/resource resource-name)) 19 | 20 | {:keys [compiler] :as cp} 21 | (classpath/start (io/file "tmp" "test-cache-root")) 22 | 23 | info 24 | (JsInspector/getFileInfoMap 25 | compiler 26 | (closure/closure-source-file resource-name source))] 27 | 28 | (tap> info) 29 | 30 | (classpath/stop cp) 31 | )) 32 | 33 | -------------------------------------------------------------------------------- /src/repl/shadow/build/targets/foo_test.clj: -------------------------------------------------------------------------------- 1 | (ns shadow.build.targets.foo-test 2 | (:require [clojure.test :refer :all] 3 | [clojure.pprint :refer (pprint)] 4 | [shadow.build.targets.browser :as browser])) 5 | 6 | (deftest browser-rewrite-modules 7 | (let [x (browser/rewrite-modules 8 | {:worker-info {:host "localhost" :port 1234} 9 | :js-options {:js-provider :require}} 10 | :dev 11 | '{:modules {:main {:entries [my.app]} 12 | :blubb {:entries [foo.bar] 13 | :preloads [foo.preload] 14 | :depends-on #{:main}}} 15 | :devtools 16 | {:preloads [app.preload]}})] 17 | (pprint x) 18 | )) 19 | -------------------------------------------------------------------------------- /src/repl/shadow/build/test_test.clj: -------------------------------------------------------------------------------- 1 | (ns shadow.build.test-test ;; lol 2 | (:require [clojure.test :refer :all] 3 | [clojure.pprint :refer (pprint)] 4 | [shadow.cljs.devtools.api :as api] 5 | [shadow.cljs.devtools.config :as config] 6 | [shadow.build.api :as build-api] 7 | [shadow.build.test :as build-test] 8 | [clojure.java.io :as io] 9 | [shadow.build.node :as node])) 10 | 11 | 12 | (deftest test-runner-generator 13 | 14 | 15 | 16 | 17 | ) -------------------------------------------------------------------------------- /src/repl/shadow/chokidar.cljs: -------------------------------------------------------------------------------- 1 | (ns shadow.chokidar 2 | (:require ["chokidar" :refer (watch)])) 3 | 4 | 5 | (def watcher 6 | (watch 7 | #js ["src/dev" "src/main" "src/test"] 8 | #js {})) 9 | 10 | (defn watch-callback [event path] 11 | (js/console.log event path)) 12 | 13 | (defn main [& args] 14 | (.on watcher "all" watch-callback)) -------------------------------------------------------------------------------- /src/repl/shadow/cljs/closure_test.clj: -------------------------------------------------------------------------------- 1 | (ns shadow.cljs.closure-test 2 | (:require [clojure.test :refer (deftest is)] 3 | [clojure.pprint :refer (pprint)] 4 | [shadow.build.closure :as closure] 5 | [shadow.build.data :as data] 6 | [clojure.java.io :as io]) 7 | (:import (com.google.javascript.jscomp ShadowAccess ClosureRewriteModule CompilerOptions CompilerOptions$LanguageMode) 8 | [com.google.javascript.jscomp.transpile BaseTranspiler] 9 | [java.net URI])) 10 | 11 | 12 | (deftest test-get-externs-properties 13 | (let [cc 14 | (data/make-closure-compiler) 15 | 16 | co 17 | (closure/make-options) 18 | 19 | externs 20 | @closure/default-externs 21 | 22 | result 23 | (.compile cc externs [] co)] 24 | 25 | (prn (ShadowAccess/getExternProperties cc)) 26 | )) 27 | 28 | (deftest test-transpile-goog-module 29 | (let [transpiler 30 | BaseTranspiler/ES5_TRANSPILER 31 | 32 | code 33 | (slurp (io/resource "goog/loader/activemodulemanager.js")) 34 | 35 | result 36 | (.transpile transpiler (URI. "/foo/bar.js") code)] 37 | 38 | (println (.transpiled result)) 39 | ;; (prn result) 40 | )) -------------------------------------------------------------------------------- /src/repl/shadow/cljs/deps_test.clj: -------------------------------------------------------------------------------- 1 | (ns shadow.cljs.deps-test 2 | (:require [clojure.test :refer (deftest is)] 3 | [clojure.pprint :refer (pprint)] 4 | 5 | [clojure.tools.deps.alpha :as deps] 6 | [clojure.tools.deps.alpha.util.maven :as mvn-util] 7 | [clojure.tools.deps.alpha.providers.local] 8 | [clojure.tools.deps.alpha.providers.maven] 9 | [clojure.tools.deps.alpha.providers :as providers] 10 | #_ [cemerick.pomegranate.aether :as pom]) 11 | (:import (clojure.lang PersistentQueue))) 12 | 13 | (deftest test-tools-deps 14 | (pprint (deps/resolve-deps 15 | {:deps '{thheller/shadow-cljs {:mvn/version "2.0.70"}} 16 | :mvn/repos mvn-util/standard-repos} 17 | {}))) 18 | 19 | (comment 20 | (deftest test-pomegranate 21 | 22 | (pprint (pom/resolve-dependencies 23 | :repositories 24 | {"central" "https://repo1.maven.org/maven2/" 25 | "clojars" "https://clojars.org/repo/"} 26 | :coordinates 27 | [['thheller/shadow-cljs "2.0.59"]])))) 28 | 29 | -------------------------------------------------------------------------------- /src/repl/shadow/cljs/devtools/FSTest.java: -------------------------------------------------------------------------------- 1 | package shadow.util; 2 | 3 | 4 | import clojure.lang.RT; 5 | 6 | import java.io.File; 7 | import java.io.IOException; 8 | import java.nio.file.Paths; 9 | import java.util.ArrayList; 10 | import java.util.Arrays; 11 | import java.util.List; 12 | 13 | /** 14 | * Created by zilence on 05.06.15. 15 | */ 16 | // @RunWith(JUnit4.class) 17 | public class FSTest { 18 | 19 | 20 | // @Test 21 | public void testListFiles() throws IOException, InterruptedException { 22 | Object result = FS.findFilesByExt(Paths.get("cljs-data", "css"), "scss"); 23 | System.out.println(result); 24 | 25 | result = FS.glob(Paths.get("cljs-data", "css"), "*.scss"); 26 | System.out.println(result); 27 | 28 | result = FS.glob(Paths.get("cljs-data", "css"), "**/*.scss"); 29 | System.out.println(result); 30 | 31 | File toBeCreated = new File("cljs-data/css/created.scss"); 32 | if (toBeCreated.exists()) { 33 | toBeCreated.delete(); 34 | } 35 | toBeCreated.deleteOnExit(); 36 | 37 | File toBeDeleted = new File("cljs-data/css/deleted.scss"); 38 | if (!toBeDeleted.exists()) { 39 | toBeDeleted.createNewFile(); 40 | } 41 | toBeDeleted.deleteOnExit(); 42 | 43 | File dontCare = new File("cljs-data/css/dont-care.txt"); 44 | dontCare.deleteOnExit(); 45 | 46 | List exts = new ArrayList<>(); 47 | exts.add("scss"); 48 | 49 | FileWatcher wd = FileWatcher.create(Paths.get("cljs-data", "css"), exts); 50 | 51 | File file = new File("cljs-data/css/includes/nested/deeper.scss"); 52 | file.setLastModified(System.currentTimeMillis()); 53 | 54 | toBeCreated.createNewFile(); 55 | toBeDeleted.delete(); 56 | dontCare.createNewFile(); 57 | 58 | System.out.println(wd.waitForChanges()); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/repl/shadow/cljs/devtools/nrepl_test.clj: -------------------------------------------------------------------------------- 1 | (ns shadow.cljs.devtools.nrepl-test 2 | (:require [clojure.test :refer :all] 3 | [clojure.pprint :refer (pprint)] 4 | [clojure.tools.nrepl :as client] 5 | [clojure.tools.nrepl.server :as server] 6 | [shadow.cljs.devtools.nrepl :as dt-nrepl] 7 | [clojure.edn :as edn])) 8 | 9 | (def TEST-PORT 55555) 10 | 11 | (defn call [conn op args] 12 | (-> (client/client conn 2000) 13 | (client/message {:op op :args (pr-str args)}) 14 | (client/response-values) 15 | (as-> x 16 | (map edn/read-string x)))) 17 | 18 | (defn start-server [] 19 | (server/start-server 20 | :port TEST-PORT 21 | :handler (server/default-handler 22 | #'dt-nrepl/wrap-devtools))) 23 | 24 | (deftest test-nrepl-setup 25 | (cljs/start! {:verbose true}) 26 | (with-open [srv (start-server)] 27 | (with-open [conn (client/connect :port TEST-PORT)] 28 | ;; (pprint (call conn :cljs/list-builds {})) 29 | (pprint (call conn :cljs/start-worker {:build :browser :autobuild true})) 30 | (pprint (call conn :cljs/sync {:build :browser})) 31 | ;; (pprint (call conn :cljs/start-build {:build :script :opts {:autobuild true}})) 32 | )) 33 | (cljs/stop!)) 34 | 35 | 36 | 37 | (comment 38 | (cljs/start! {:verbose true}) 39 | (cljs/stop!) 40 | 41 | (def server (start-server)) 42 | 43 | (.close server)) 44 | 45 | -------------------------------------------------------------------------------- /src/repl/shadow/cljs/foreign_test.clj: -------------------------------------------------------------------------------- 1 | (ns shadow.cljs.foreign-test 2 | (:require [clojure.test :refer :all] 3 | [clojure.pprint :refer (pprint)] 4 | [clojure.edn :as edn] 5 | [shadow.build.closure :as closure] 6 | [cljs.closure] 7 | [clojure.java.io :as io] 8 | [shadow.cljs.util :as util] 9 | ;; too much util ... 10 | [shadow.cljs.devtools.server.util :as server-util] 11 | [clojure.string :as str] 12 | [clojure.data.json :as json] 13 | [shadow.build.ns-form :as ns-form] 14 | [shadow.build.api :as cljs] 15 | [shadow.build :as comp] 16 | [shadow.cljs.devtools.api :as api] 17 | [shadow.build.npm :as npm] 18 | [clojure.inspector :as i]) 19 | (:import (com.google.javascript.jscomp SourceFile DiagnosticGroups CheckLevel CompilerOptions CodePrinter$Builder CompilerOptions$LanguageMode) 20 | (com.google.javascript.jscomp.deps ModuleLoader$ResolutionMode) 21 | (java.io File StringWriter))) 22 | 23 | -------------------------------------------------------------------------------- /src/repl/shadow/cljs/release_snapshot_test.clj: -------------------------------------------------------------------------------- 1 | (ns shadow.cljs.release-snapshot-test 2 | (:require 3 | [clojure.test :refer (deftest is)] 4 | [clojure.edn :as edn] 5 | [clojure.java.io :as io] 6 | [shadow.cljs.build-report :as snap])) 7 | 8 | 9 | (deftest test-print-table 10 | (let [bundle-info 11 | (-> (io/file ".shadow-cljs" "release-snapshots" "browser" "latest" "bundle-info.edn") 12 | (slurp) 13 | (edn/read-string))] 14 | 15 | (snap/print-bundle-info-table bundle-info {:group-jar true 16 | :group-npm true}) 17 | #_(snap/print-bundle-info-table bundle-info {:group-jar false 18 | :group-npm true}) 19 | #_(snap/print-bundle-info-table bundle-info {:group-jar true 20 | :group-npm false}) 21 | 22 | )) 23 | -------------------------------------------------------------------------------- /src/repl/shadow/cljs/test_util.clj: -------------------------------------------------------------------------------- 1 | (ns shadow.cljs.test-util 2 | (:require [clojure.pprint :as pp :refer (pprint)])) 3 | 4 | (defn wide-pprint [x] 5 | (binding [clojure.pprint/*print-right-margin* 120] 6 | (pprint x))) 7 | 8 | 9 | -------------------------------------------------------------------------------- /src/repl/shadow/cljs/ui_test.clj: -------------------------------------------------------------------------------- 1 | (ns shadow.cljs.ui-test 2 | (:require 3 | [clojure.test :refer (deftest is)] 4 | [clojure.pprint :refer (pprint)] 5 | [shadow.cljs.devtools.api :as api] 6 | [shadow.build.closure :as closure] 7 | [shadow.cljs.util :as util] 8 | [shadow.build.data :as data] 9 | [clojure.edn :as edn] 10 | [clojure.data.json :as json] 11 | [clojure.java.shell :refer (sh)] 12 | [clojure.java.io :as io] 13 | [shadow.build.output :as output] 14 | [shadow.build :as build] 15 | [shadow.build.api :as build-api]) 16 | (:import (java.io FileOutputStream))) 17 | 18 | (deftest test-convert-to-webpack-stats 19 | (let [{:keys [build-sources] :as data} 20 | (-> (slurp ".shadow-cljs/builds/browser/release/bundle-info.edn") 21 | (edn/read-string))] 22 | 23 | (->> {:assets [] 24 | :chunks [] 25 | :modules 26 | (->> build-sources 27 | (map-indexed 28 | (fn [idx {:keys [resource-name optimized-size js-size]}] 29 | {:id idx 30 | :identifier (str "/" resource-name) 31 | :name (str "/" resource-name) 32 | :size (or optimized-size js-size) 33 | :reasons []})) 34 | (into []))} 35 | (json/write-str) 36 | (spit (io/file "tmp/stats.json"))))) 37 | 38 | (defn flush-bundle-info [state] 39 | (let [bundle-info 40 | (output/generate-bundle-info state) 41 | 42 | bundle-file 43 | (data/cache-file state "bundle-info.edn")] 44 | 45 | (io/make-parents bundle-file) 46 | 47 | (spit bundle-file 48 | (with-out-str 49 | (pprint bundle-info)))) 50 | 51 | state) 52 | 53 | (deftest test-release-info 54 | (api/release-snapshot :browser {})) -------------------------------------------------------------------------------- /src/repl/shadow/cljs/watch_test.clj: -------------------------------------------------------------------------------- 1 | (ns shadow.cljs.watch-test 2 | (:require 3 | [clojure.test :refer (is deftest)] 4 | [clojure.java.io :as io] 5 | [shadow.cljs.devtools.server.fs-watch :as fs])) 6 | 7 | 8 | (comment 9 | (def watcher 10 | (fs-jvm/start {} 11 | [(io/file "tmp" "watch")] 12 | #{"test"} 13 | prn 14 | )) 15 | 16 | (fs-jvm/stop watcher) 17 | 18 | (def w-hawk 19 | (fs-hawk/start {} 20 | [(io/file "tmp" "watch")] 21 | #{"test"} 22 | prn 23 | )) 24 | 25 | (fs-hawk/stop w-hawk)) 26 | -------------------------------------------------------------------------------- /src/repl/shadow/closure_test.clj: -------------------------------------------------------------------------------- 1 | (ns shadow.closure-test 2 | (:require [clojure.test :as t :refer :all]) 3 | (:import (com.google.javascript.jscomp JSChunk JSChunkGraph))) 4 | 5 | 6 | (deftest test-js-module-graph-weirdness 7 | (let [mod-a 8 | (JSChunk. "a") 9 | 10 | mod-b 11 | (JSChunk. "b") 12 | 13 | mod-c 14 | (JSChunk. "c")] 15 | 16 | (.addDependency mod-c mod-a) 17 | (.addDependency mod-c mod-b) 18 | 19 | (let [graph 20 | (JSChunkGraph. (into-array [mod-a mod-b mod-c]))] 21 | 22 | (is (.dependsOn graph mod-c mod-a)) 23 | (is (.dependsOn graph mod-c mod-b)) 24 | (is (not (.dependsOn graph mod-b mod-c))) 25 | ))) -------------------------------------------------------------------------------- /src/repl/shadow/grove/insight.cljs: -------------------------------------------------------------------------------- 1 | (ns shadow.grove.insight) 2 | -------------------------------------------------------------------------------- /src/repl/shadow/insight/example__in.clj: -------------------------------------------------------------------------------- 1 | ;; # h1 2 | ;; hello world 3 | 4 | (js/console.log "yo from insight file" ::foo) 5 | 6 | (!/in-remote {:lang :clj}) 7 | 8 | (System/getenv) 9 | 10 | ;; already in it, but switching should be ok 11 | (!/in-remote {:lang :clj}) 12 | 13 | (System/getProperties) 14 | 15 | (!/in-local) 16 | 17 | (js/console.log "back in viewer") 18 | 19 | ;; ## extra1 20 | ;; hello world 21 | 22 | (require '[shadow.grove.insight]) 23 | (require '[shadow.grove :as sg :refer (defc <<)]) 24 | 25 | (<< [:h1 "hello world!"]) 26 | 27 | ;; trailing comment? -------------------------------------------------------------------------------- /src/repl/shadow/insight_test.clj: -------------------------------------------------------------------------------- 1 | (ns shadow.insight-test 2 | (:require 3 | [clojure.java.io :as io] 4 | [clojure.pprint :refer (pprint)] 5 | [clojure.test :as ct :refer (deftest is)] 6 | [rewrite-clj.node :as n] 7 | [rewrite-clj.parser :as p] 8 | [rewrite-clj.zip :as z] 9 | [shadow.insight.parser :as sip])) 10 | 11 | (deftest parsing 12 | (let [content 13 | (slurp (io/resource "shadow/insight/example__in.clj")) 14 | 15 | blocks 16 | (sip/parse content)] 17 | 18 | (tap> blocks) 19 | )) 20 | 21 | (deftest markdown-parsing 22 | (let [text "# yo\nhello world\n```foo```"] 23 | (prn (sip/md->data text)) 24 | )) -------------------------------------------------------------------------------- /src/repl/shadow/undertow_test.clj: -------------------------------------------------------------------------------- 1 | (ns shadow.undertow-test 2 | (:require 3 | [clojure.test :as ct :refer (deftest is)] 4 | [shadow.undertow :as u] 5 | [clojure.java.io :as io] 6 | [shadow.undertow.impl :as impl]) 7 | (:import [io.undertow.server HttpHandler] 8 | [io.undertow.server.handlers.resource ClassPathResourceManager ResourceHandler PathResourceManager] 9 | [java.io File] 10 | [io.undertow Handlers] 11 | [io.undertow.server.handlers BlockingHandler])) 12 | 13 | 14 | (deftest undertow-handlers 15 | (let [http-handler-fn 16 | (fn [ring-map] {:status 200}) 17 | 18 | root-dir 19 | (io/file "tmp") 20 | 21 | state 22 | (u/build {} 23 | [::u/ws-upgrade 24 | ;; "Upgrade" requests 25 | [::u/ring {:handler http-handler-fn}] 26 | ;; normal 27 | [::u/classpath {:root "some/path"} 28 | [::u/file {:root-dir root-dir} 29 | [::u/classpath {:root "shadow/cljs/devtools/server/dev_http"} 30 | [::u/disable-cache 31 | [::u/blocking 32 | [::u/ring {:handler http-handler-fn}]]]]]]])] 33 | 34 | (prn state) 35 | 36 | (u/close-handlers state) 37 | )) 38 | -------------------------------------------------------------------------------- /src/repl/test.externs.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * @constructor 4 | */ 5 | var Foreign = function() {}; 6 | 7 | Foreign.prototype.foo; -------------------------------------------------------------------------------- /src/repl/test/bar.cljs: -------------------------------------------------------------------------------- 1 | (ns test.bar) 2 | 3 | (js/console.log "bar") 4 | 5 | (defn bar [x] 6 | (js/console.log "bar" x)) -------------------------------------------------------------------------------- /src/repl/test/empty.cljs: -------------------------------------------------------------------------------- 1 | (ns test.empty) -------------------------------------------------------------------------------- /src/repl/test/ext.js: -------------------------------------------------------------------------------- 1 | goog.provide("test.ext"); 2 | 3 | /** 4 | * @constructor 5 | */ 6 | test.ext.Foo = function(x) { 7 | this.foo = x; 8 | } 9 | 10 | function dummy(/** test.ext.Foo */ x) { 11 | console.log(x.foo); 12 | } 13 | 14 | dummy(new test.ext.Foo("1")); 15 | dummy(new test.ext.Foo("2")); 16 | dummy(new test.ext.Foo("3")); 17 | 18 | 19 | -------------------------------------------------------------------------------- /src/repl/test/perf.cljs: -------------------------------------------------------------------------------- 1 | (ns test.perf) 2 | 3 | -------------------------------------------------------------------------------- /src/repl/test/snippet.cljs: -------------------------------------------------------------------------------- 1 | (ns test.snippet) 2 | 3 | (set! *warn-on-infer* true) 4 | 5 | (defn foo [x] 6 | (.bar x)) 7 | 8 | (list) 9 | 10 | (js/React.createElement "foo") -------------------------------------------------------------------------------- /src/test/circular/foo.cljs: -------------------------------------------------------------------------------- 1 | (ns circular.foo 2 | (:require [circular.util.lib])) -------------------------------------------------------------------------------- /src/test/circular/main.cljs: -------------------------------------------------------------------------------- 1 | (ns circular.main 2 | (:require [circular.foo])) -------------------------------------------------------------------------------- /src/test/circular/util/lib.cljs: -------------------------------------------------------------------------------- 1 | (ns circular.util.lib 2 | (:require [circular.foo])) -------------------------------------------------------------------------------- /src/test/foo.js: -------------------------------------------------------------------------------- 1 | // dummy test file 2 | module.exports = require("./bar"); -------------------------------------------------------------------------------- /src/test/shadow/build/closure/ReplaceRequirePassTest.java: -------------------------------------------------------------------------------- 1 | package shadow.build.closure; 2 | 3 | import com.google.javascript.jscomp.*; 4 | import com.google.javascript.jscomp.Compiler; 5 | import com.google.javascript.rhino.Node; 6 | 7 | import java.util.HashMap; 8 | import java.util.Map; 9 | 10 | public class ReplaceRequirePassTest { 11 | 12 | public static Node process(Compiler cc, SourceFile srcFile) { 13 | CompilerInput ast = new CompilerInput(srcFile); 14 | Node node = ast.getAstRoot(cc); 15 | 16 | // JsAst.ParseResult result = (JsAst.ParseResult) node.getProp(Node.PARSE_RESULTS); 17 | 18 | Map nested = new HashMap<>(); 19 | nested.put("test", "module$test"); 20 | 21 | Map> outer = new HashMap<>(); 22 | outer.put("test.js", nested); 23 | 24 | NodeTraversal.Callback pass = new ReplaceRequirePass(cc, outer); 25 | NodeTraversal.traverse(cc, node, pass); 26 | 27 | return node; 28 | } 29 | 30 | public static void main(String... args) { 31 | Compiler cc = new Compiler(); 32 | 33 | CompilerOptions co = new CompilerOptions(); 34 | co.setLanguageIn(CompilerOptions.LanguageMode.ECMASCRIPT_2017); 35 | co.setPrettyPrint(true); 36 | cc.initOptions(co); 37 | 38 | SourceFile srcFile = SourceFile.fromCode("test.js", "require('test'); require('goog:goog.string');"); 39 | 40 | System.out.println(cc.toSource(process(cc, srcFile))); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/test/shadow/build/closure/SourceMapReportTest.java: -------------------------------------------------------------------------------- 1 | package shadow.build.closure; 2 | 3 | import java.io.File; 4 | 5 | public class SourceMapReportTest { 6 | 7 | public static void main(String[] args) throws Exception { 8 | File releaseDir = new File(".shadow-cljs/release-snapshots/browser/latest"); 9 | File sourceFile = new File(releaseDir, "demo.js"); 10 | File sourceMapFile = new File(releaseDir, "demo.js.map"); 11 | 12 | System.out.println(SourceMapReport.getByteMap(sourceFile, sourceMapFile)); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/test/shadow/undertow_test.clj: -------------------------------------------------------------------------------- 1 | (ns shadow.undertow-test 2 | (:require [clojure.test :refer :all] 3 | [clojure.string :as str] 4 | [shadow.undertow :as undertow]) 5 | (:import [io.undertow.util HeaderMap HttpString])) 6 | 7 | (def test-cookie "shadow-cljs/session=111222333; Max-Age=1295940; Path=/; HttpOnly; Secure; SameSite=Lax") 8 | 9 | (deftest unset-secure-cookie-check 10 | (testing "Verifies that the unset-secure-cookie feature properly parses cookie strings" 11 | (let [headers 12 | (doto (HeaderMap.) 13 | (.put (HttpString. "set-cookie") test-cookie))] 14 | (is (str/includes? test-cookie "Secure;")) 15 | (undertow/unset-secure-cookie headers) 16 | (let [cookie (.get headers "set-cookie" 0)] 17 | (is (str/includes? cookie "HttpOnly;")) 18 | (is (not (str/includes? cookie "Secure;"))))))) 19 | -------------------------------------------------------------------------------- /src/ui-release/shadow/cljs/ui/dist/css/.gitignore: -------------------------------------------------------------------------------- 1 | *.css -------------------------------------------------------------------------------- /src/ui-release/shadow/cljs/ui/dist/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thheller/shadow-cljs/efd77b59a1f89a6c877e8471c26f127095271ec5/src/ui-release/shadow/cljs/ui/dist/favicon.ico -------------------------------------------------------------------------------- /src/ui-release/shadow/cljs/ui/dist/img/shadow-cljs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thheller/shadow-cljs/efd77b59a1f89a6c877e8471c26f127095271ec5/src/ui-release/shadow/cljs/ui/dist/img/shadow-cljs.png -------------------------------------------------------------------------------- /src/ui-release/shadow/cljs/ui/dist/img/shadow-cljs.svg: -------------------------------------------------------------------------------- 1 | 6 | shadow-cljs 7 | -------------------------------------------------------------------------------- /tailwind.config.js: -------------------------------------------------------------------------------- 1 | 2 | let filesToPurge; 3 | 4 | if (process.env.NODE_ENV == "production") { 5 | filesToPurge = ["src/ui-release/shadow/cljs/ui/dist/js/*.js"]; 6 | } else { 7 | filesToPurge = [".shadow-cljs/ui/js/cljs-runtime/*.js"]; 8 | } 9 | 10 | module.exports = { 11 | content: filesToPurge, 12 | plugins: [ 13 | require('@tailwindcss/forms') 14 | ] 15 | } -------------------------------------------------------------------------------- /test-env/node_modules/@scoped/a/index.js: -------------------------------------------------------------------------------- 1 | 1; 2 | -------------------------------------------------------------------------------- /test-env/node_modules/@scoped/a/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@scoped/a", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC" 12 | } 13 | -------------------------------------------------------------------------------- /test-env/node_modules/browser-override/index.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thheller/shadow-cljs/efd77b59a1f89a6c877e8471c26f127095271ec5/test-env/node_modules/browser-override/index.js -------------------------------------------------------------------------------- /test-env/node_modules/browser-override/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "browser-override", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC" 12 | } 13 | -------------------------------------------------------------------------------- /test-env/node_modules/browser-override/web/dist/server.cjs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thheller/shadow-cljs/efd77b59a1f89a6c877e8471c26f127095271ec5/test-env/node_modules/browser-override/web/dist/server.cjs -------------------------------------------------------------------------------- /test-env/node_modules/browser-override/web/dist/web.cjs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thheller/shadow-cljs/efd77b59a1f89a6c877e8471c26f127095271ec5/test-env/node_modules/browser-override/web/dist/web.cjs -------------------------------------------------------------------------------- /test-env/node_modules/browser-override/web/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "browser-override/web", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "./dist/server.cjs", 6 | "module": "./dist/server.js", 7 | "browser": { 8 | "./dist/server.cjs": "./dist/web.cjs", 9 | "./dist/server.js": "./dist/web.js", 10 | "false-package": false 11 | }, 12 | "scripts": { 13 | "test": "echo \"Error: no test specified\" && exit 1" 14 | }, 15 | "keywords": [], 16 | "author": "", 17 | "license": "ISC" 18 | } 19 | -------------------------------------------------------------------------------- /test-env/node_modules/dep-a/index.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thheller/shadow-cljs/efd77b59a1f89a6c877e8471c26f127095271ec5/test-env/node_modules/dep-a/index.js -------------------------------------------------------------------------------- /test-env/node_modules/dep-a/node_modules/dep-b/index.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thheller/shadow-cljs/efd77b59a1f89a6c877e8471c26f127095271ec5/test-env/node_modules/dep-a/node_modules/dep-b/index.js -------------------------------------------------------------------------------- /test-env/node_modules/dep-a/node_modules/dep-b/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "dep-b", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC" 12 | } 13 | -------------------------------------------------------------------------------- /test-env/node_modules/dep-a/node_modules/dep-c/index.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thheller/shadow-cljs/efd77b59a1f89a6c877e8471c26f127095271ec5/test-env/node_modules/dep-a/node_modules/dep-c/index.js -------------------------------------------------------------------------------- /test-env/node_modules/dep-a/node_modules/dep-c/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "dep-c", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC" 12 | } 13 | -------------------------------------------------------------------------------- /test-env/node_modules/dep-a/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "dep-a", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC" 12 | } 13 | -------------------------------------------------------------------------------- /test-env/node_modules/dir.js/main.js: -------------------------------------------------------------------------------- 1 | 1; 2 | -------------------------------------------------------------------------------- /test-env/node_modules/dir.js/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "dir.js", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "main.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC" 12 | } 13 | -------------------------------------------------------------------------------- /test-env/node_modules/dyn-import/dynamic.js: -------------------------------------------------------------------------------- 1 | 2 | console.log("loading dynamic import file"); 3 | 4 | export function bar() { 5 | return "bar"; 6 | } 7 | -------------------------------------------------------------------------------- /test-env/node_modules/dyn-import/index.js: -------------------------------------------------------------------------------- 1 | import foo from "./regular.js"; 2 | 3 | export function bar() { 4 | return import("./dynamic.js"); 5 | } 6 | -------------------------------------------------------------------------------- /test-env/node_modules/dyn-import/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "dyn-import", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC" 12 | } 13 | -------------------------------------------------------------------------------- /test-env/node_modules/dyn-import/regular.js: -------------------------------------------------------------------------------- 1 | export default "yo"; 2 | -------------------------------------------------------------------------------- /test-env/node_modules/entry-dir/foo/index.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thheller/shadow-cljs/efd77b59a1f89a6c877e8471c26f127095271ec5/test-env/node_modules/entry-dir/foo/index.js -------------------------------------------------------------------------------- /test-env/node_modules/entry-dir/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "entry-dir", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC" 12 | } 13 | -------------------------------------------------------------------------------- /test-env/node_modules/exports/foo.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thheller/shadow-cljs/efd77b59a1f89a6c877e8471c26f127095271ec5/test-env/node_modules/exports/foo.js -------------------------------------------------------------------------------- /test-env/node_modules/exports/other/foo.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thheller/shadow-cljs/efd77b59a1f89a6c877e8471c26f127095271ec5/test-env/node_modules/exports/other/foo.js -------------------------------------------------------------------------------- /test-env/node_modules/exports/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "exports", 3 | "version": "1.0.0", 4 | "description": "", 5 | "keywords": [], 6 | "author": "", 7 | "license": "ISC", 8 | "exports": { 9 | ".": "./foo.js", 10 | "./foo": "./foo.js", 11 | "./prefix/": "./other/", 12 | "./wildcard/*": "./other/*.js", 13 | "./wildcard-with-suffix/*.js": "./other/*.js" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /test-env/node_modules/extra-js-package-dir/extra-package/index.js: -------------------------------------------------------------------------------- 1 | modules.exports = "foo"; -------------------------------------------------------------------------------- /test-env/node_modules/extra-js-package-dir/extra-package/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "extra-package", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC" 12 | } 13 | -------------------------------------------------------------------------------- /test-env/node_modules/file-over-dir/foo.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thheller/shadow-cljs/efd77b59a1f89a6c877e8471c26f127095271ec5/test-env/node_modules/file-over-dir/foo.js -------------------------------------------------------------------------------- /test-env/node_modules/file-over-dir/foo/bar.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thheller/shadow-cljs/efd77b59a1f89a6c877e8471c26f127095271ec5/test-env/node_modules/file-over-dir/foo/bar.js -------------------------------------------------------------------------------- /test-env/node_modules/file-over-dir/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "file-over-dir", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "foo.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC" 12 | } 13 | -------------------------------------------------------------------------------- /test-env/node_modules/implicits/index.js: -------------------------------------------------------------------------------- 1 | var x = Buffer.alloc(4); 2 | 3 | process.nextTick(function() { console.log(x); }); -------------------------------------------------------------------------------- /test-env/node_modules/implicits/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "implicits", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC" 12 | } 13 | -------------------------------------------------------------------------------- /test-env/node_modules/lvl1/index.js: -------------------------------------------------------------------------------- 1 | module.exports = require("lvl2"); 2 | -------------------------------------------------------------------------------- /test-env/node_modules/lvl1/node_modules/lvl2/index.js: -------------------------------------------------------------------------------- 1 | module.exports = 2; 2 | -------------------------------------------------------------------------------- /test-env/node_modules/lvl1/node_modules/lvl2/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "lvl2", 3 | "version": "2.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC" 12 | } 13 | -------------------------------------------------------------------------------- /test-env/node_modules/lvl1/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "lvl1", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC" 12 | } 13 | -------------------------------------------------------------------------------- /test-env/node_modules/lvl2/index.js: -------------------------------------------------------------------------------- 1 | module.exports = 1; 2 | -------------------------------------------------------------------------------- /test-env/node_modules/lvl2/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "lvl2", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC" 12 | } 13 | -------------------------------------------------------------------------------- /test-env/node_modules/main-is-dir/lib/index.js: -------------------------------------------------------------------------------- 1 | 1; 2 | -------------------------------------------------------------------------------- /test-env/node_modules/main-is-dir/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "main-is-dir", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "lib", 6 | "keywords": [], 7 | "author": "", 8 | "license": "ISC" 9 | } 10 | -------------------------------------------------------------------------------- /test-env/node_modules/nested-but-not-really/bar.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thheller/shadow-cljs/efd77b59a1f89a6c877e8471c26f127095271ec5/test-env/node_modules/nested-but-not-really/bar.js -------------------------------------------------------------------------------- /test-env/node_modules/nested-but-not-really/foo.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thheller/shadow-cljs/efd77b59a1f89a6c877e8471c26f127095271ec5/test-env/node_modules/nested-but-not-really/foo.js -------------------------------------------------------------------------------- /test-env/node_modules/nested-but-not-really/index.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thheller/shadow-cljs/efd77b59a1f89a6c877e8471c26f127095271ec5/test-env/node_modules/nested-but-not-really/index.js -------------------------------------------------------------------------------- /test-env/node_modules/nested-but-not-really/nested/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "nested-but-not-really/nested", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "../foo.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC" 12 | } 13 | -------------------------------------------------------------------------------- /test-env/node_modules/nested-but-not-really/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "nested-but-not-really", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC" 12 | } 13 | -------------------------------------------------------------------------------- /test-env/node_modules/nested-pkg/just-index/index.js: -------------------------------------------------------------------------------- 1 | 1; 2 | -------------------------------------------------------------------------------- /test-env/node_modules/nested-pkg/just-index/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "nested-pkg/just-index" 3 | } 4 | -------------------------------------------------------------------------------- /test-env/node_modules/nested-pkg/nested/main.js: -------------------------------------------------------------------------------- 1 | console.log("hello world main.js") 2 | -------------------------------------------------------------------------------- /test-env/node_modules/nested-pkg/nested/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "nested-pkg/nested", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "main.js", 6 | "module": "index.js", 7 | "scripts": { 8 | "test": "echo \"Error: no test specified\" && exit 1" 9 | }, 10 | "keywords": [], 11 | "author": "", 12 | "license": "ISC" 13 | } 14 | -------------------------------------------------------------------------------- /test-env/node_modules/nested-pkg/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "nested-pkg", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC" 12 | } 13 | -------------------------------------------------------------------------------- /test-env/node_modules/nested-pkg/relative/index.js: -------------------------------------------------------------------------------- 1 | require("../nested") -------------------------------------------------------------------------------- /test-env/node_modules/pkg-a/index-browser.js: -------------------------------------------------------------------------------- 1 | module.exports = "browser"; -------------------------------------------------------------------------------- /test-env/node_modules/pkg-a/index.js: -------------------------------------------------------------------------------- 1 | module.exports = "index"; -------------------------------------------------------------------------------- /test-env/node_modules/pkg-a/nested/thing.js: -------------------------------------------------------------------------------- 1 | module.exports = require(".."); -------------------------------------------------------------------------------- /test-env/node_modules/pkg-a/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "pkg-a", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "browser":{ 7 | "./index.js":"./index-browser.js" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /test-env/node_modules/pkg-nested-override/dir/bar.js: -------------------------------------------------------------------------------- 1 | require("./foo") -------------------------------------------------------------------------------- /test-env/node_modules/pkg-nested-override/dir/foo.browser.js: -------------------------------------------------------------------------------- 1 | module.exports = "ok"; -------------------------------------------------------------------------------- /test-env/node_modules/pkg-nested-override/dir/foo.js: -------------------------------------------------------------------------------- 1 | SHOULD NOT BE INCLUDED! -------------------------------------------------------------------------------- /test-env/node_modules/pkg-nested-override/index.js: -------------------------------------------------------------------------------- 1 | require("./dir/bar.js") -------------------------------------------------------------------------------- /test-env/node_modules/pkg-nested-override/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "pkg-nested-override", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "browser":{ 7 | "./dir/foo.js": "./dir/foo.browser.js", 8 | "pkg": "./pkg-override.js", 9 | "fs": false 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /test-env/node_modules/pkg-nested-override/pkg-override.js: -------------------------------------------------------------------------------- 1 | module.exports = "foo"; -------------------------------------------------------------------------------- /test-env/node_modules/with-assets/foo.css: -------------------------------------------------------------------------------- 1 | body { color: red; } 2 | -------------------------------------------------------------------------------- /test-env/node_modules/with-assets/index.js: -------------------------------------------------------------------------------- 1 | require("./foo.css") 2 | 3 | module.exports = "foo"; 4 | -------------------------------------------------------------------------------- /test-env/node_modules/with-assets/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "with-assets", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC" 12 | } 13 | -------------------------------------------------------------------------------- /test-project/.gitignore: -------------------------------------------------------------------------------- 1 | launcher.jar 2 | out/ 3 | -------------------------------------------------------------------------------- /test-project/ci-run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | 5 | npm install 6 | 7 | npx shadow-cljs --cli-info 8 | 9 | npx shadow-cljs clj-run test.runnable/foo 10 | 11 | npx shadow-cljs release reagent test-node test-karma --verbose 12 | 13 | node out/test-node/script.js 14 | 15 | npx karma start --single-run -------------------------------------------------------------------------------- /test-project/karma.conf.js: -------------------------------------------------------------------------------- 1 | module.exports = function(config) { 2 | config.set({ 3 | browsers: ['CustomChrome'], 4 | customLaunchers: { 5 | CustomChrome: { 6 | base: 'ChromeHeadless', 7 | flags: ['--no-sandbox', '--disable-features=VizDisplayCompositor'] 8 | } 9 | }, 10 | basePath: 'out/test-karma', 11 | files: ['script.js'], 12 | frameworks: ['cljs-test'], 13 | plugins: ['karma-cljs-test', 'karma-chrome-launcher'], 14 | colors: true, 15 | logLevel: config.LOG_INFO, 16 | // FIXME: do we need this? 17 | client: {args: ["shadow.test.karma.init"], 18 | singleRun: true} 19 | }) 20 | }; 21 | -------------------------------------------------------------------------------- /test-project/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "test-project", 3 | "version": "1.0.0", 4 | "private": true, 5 | "description": "", 6 | "main": "index.js", 7 | "scripts": { 8 | "test": "echo \"Error: no test specified\" && exit 1" 9 | }, 10 | "keywords": [], 11 | "author": "", 12 | "license": "ISC", 13 | "dependencies": { 14 | "create-react-class": "^15.6.3", 15 | "karma": "^5.2.3", 16 | "karma-chrome-launcher": "^3.1.0", 17 | "karma-cljs-test": "^0.1.0", 18 | "react": "^16.4.2", 19 | "react-dom": "^16.4.2", 20 | "shadow-cljs": "file:../packages/shadow-cljs", 21 | "shadow-cljs-jar": "file:../packages/shadow-cljs-jar" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /test-project/shadow-cljs.edn: -------------------------------------------------------------------------------- 1 | ;; shadow-cljs configuration 2 | {:source-paths 3 | ["src/main"] 4 | 5 | :log 6 | {:level :debug} 7 | 8 | :jvm-opts ["-Dclojure.main.report=out" "-Xmx1G"] 9 | 10 | :dependencies 11 | [[reagent "0.8.1"] 12 | [funcool/bide "1.6.0"] 13 | [com.andrewmcveigh/cljs-time "0.5.2"] 14 | ;; [re-frame "0.10.5"] 15 | ;; [fulcrologic/fulcro "2.6.0-RC6"] 16 | ] 17 | 18 | :builds 19 | {:reagent 20 | {:target :browser 21 | :output-dir "out/reagent" 22 | :modules {:main {:init-fn test.reagent/init}}} 23 | 24 | :test-node 25 | {:target :node-test 26 | :output-to "out/test-node/script.js" 27 | :compiler-options {:infer-externs :auto}} 28 | 29 | :test-karma 30 | {:target :karma 31 | :output-to "out/test-karma/script.js" 32 | :compiler-options {:source-map true}} 33 | }} 34 | -------------------------------------------------------------------------------- /test-project/src/main/test/cjs.js: -------------------------------------------------------------------------------- 1 | exports.foo = "cjs/foo"; 2 | exports.bar = "cjs/bar"; -------------------------------------------------------------------------------- /test-project/src/main/test/converted-esm.js: -------------------------------------------------------------------------------- 1 | // babel converted es6.js (with changed export values) 2 | "use strict"; 3 | 4 | Object.defineProperty(exports, "__esModule", { 5 | value: true 6 | }); 7 | 8 | var _cjs = require("./cjs"); 9 | 10 | Object.defineProperty(exports, "bar", { 11 | enumerable: true, 12 | get: function get() { 13 | return _cjs.bar; 14 | } 15 | }); 16 | var foo = exports.foo = "esm/foo"; 17 | exports.default = "esm-default"; -------------------------------------------------------------------------------- /test-project/src/main/test/es6.js: -------------------------------------------------------------------------------- 1 | import cljs from "goog:cljs.core"; 2 | import { foo as foo_other } from "./esm_other.js"; 3 | 4 | export let foo = "es6/foo"; 5 | export let map = cljs.assoc(null, "a", 1); 6 | export default "es6-default"; 7 | export let nested = { extra: { bar: 1 }}; 8 | 9 | export function other_foo() { 10 | return foo_other; 11 | } -------------------------------------------------------------------------------- /test-project/src/main/test/esm_other.js: -------------------------------------------------------------------------------- 1 | export const foo = "foo"; 2 | -------------------------------------------------------------------------------- /test-project/src/main/test/foo.cljs: -------------------------------------------------------------------------------- 1 | (ns test.foo) 2 | 3 | (js/console.log "foo") -------------------------------------------------------------------------------- /test-project/src/main/test/infer_test.cljs: -------------------------------------------------------------------------------- 1 | (ns test.infer-test 2 | (:require [cljs.test :as ct :refer (use-fixtures deftest is async testing)])) 3 | 4 | (use-fixtures :once 5 | {:before 6 | (fn [] 7 | (js/console.log "fixture-once-before")) 8 | :after 9 | (fn [] 10 | (js/console.log "fixture-once-after"))}) 11 | 12 | (use-fixtures :each 13 | {:before 14 | (fn [] 15 | (js/console.log "fixture-each-before")) 16 | :after 17 | (fn [] 18 | (js/console.log "fixture-each-after"))}) 19 | 20 | (defn obj-property [^js thing] 21 | (.inferMe thing)) 22 | 23 | (deftest can-properly-call-obj 24 | (is (true? (obj-property #js {"inferMe" (constantly true)})))) 25 | 26 | (deftest dummy-test 27 | (testing "dummy nested" 28 | (is (= 1 1)))) 29 | 30 | (deftest async-text 31 | (async done 32 | (is (= 1 1)) 33 | (println "going async") 34 | (js/setTimeout 35 | (fn [] 36 | (is (= 1 1)) 37 | (println "done async") 38 | (done)) 39 | 100))) 40 | -------------------------------------------------------------------------------- /test-project/src/main/test/js_interop_test.cljs: -------------------------------------------------------------------------------- 1 | (ns test.js-interop-test 2 | (:require 3 | [cljs.test :refer (deftest is)] 4 | ["./cjs.js" :as cjs] 5 | ["./es6.js" :as es6 :default es6-default] 6 | ["./es6.js$default" :as es6-default-sugar] 7 | ["./es6.js$nested.extra" :refer (bar)] 8 | ["./es6.js$nested.extra.bar" :as bar-direct] 9 | ["./converted-esm.js" :as converted-esm :default converted-esm-default] 10 | )) 11 | 12 | (comment 13 | (js/console.log "cjs" cjs cjs/foo cjs/bar) 14 | (js/console.log "es6" es6 es6/foo es6/bar es6/map) 15 | (js/console.log "esm" converted-esm converted-esm/foo converted-esm/bar) 16 | 17 | (deftest cjs-as 18 | (is (some? cjs)) 19 | (is (= cjs/foo "cjs/foo")) 20 | (is (= cjs/bar "cjs/bar"))) 21 | 22 | (deftest converted-esm-as 23 | (is (some? converted-esm)) 24 | (is (= converted-esm/foo "esm/foo")) 25 | (is (= converted-esm/bar "cjs/bar")) 26 | (is (= converted-esm-default "esm-default")))) 27 | 28 | (deftest es6-as 29 | (is (some? es6)) 30 | (is (= es6/foo "es6/foo")) 31 | (is (map? es6/map)) 32 | (is (= 1 (get es6/map "a"))) 33 | (is (= es6-default "es6-default")) 34 | (is (identical? es6-default es6-default-sugar)) 35 | (is (identical? es6/nested.extra.bar bar)) 36 | (is (identical? bar bar-direct))) 37 | 38 | ;; this fails, unsure what to do about this 39 | ;; https://github.com/thheller/shadow-cljs/issues/894 40 | (deftest es6-indirect 41 | ;; accessing a const from other import 42 | ;; fails because const in eval has its own scope and other evals can't see it 43 | (is (= "foo" (es6/other-foo)))) -------------------------------------------------------------------------------- /test-project/src/main/test/reagent.cljs: -------------------------------------------------------------------------------- 1 | (ns test.reagent 2 | (:require [reagent.core :as r] 3 | [bide.core] 4 | [cljs-time.core])) 5 | 6 | (defn init []) 7 | -------------------------------------------------------------------------------- /test-project/src/main/test/runnable.clj: -------------------------------------------------------------------------------- 1 | (ns test.runnable 2 | (:require 3 | ;; FIXME: there should be proper test builds for each or these 4 | ;; for now just testing if the targets actually load properly 5 | [shadow.build.targets.azure-app] 6 | [shadow.build.targets.bootstrap] 7 | [shadow.build.targets.browser] 8 | [shadow.build.targets.browser-test] 9 | [shadow.build.targets.chrome-extension] 10 | [shadow.build.targets.karma] 11 | [shadow.build.targets.node-library] 12 | [shadow.build.targets.node-script] 13 | [shadow.build.targets.node-test] 14 | [shadow.build.targets.npm-module] 15 | [shadow.build.targets.react-native])) 16 | 17 | (defn foo [] 18 | (prn :foo)) 19 | 20 | (defn foo-server 21 | {:shadow/requires-server true} 22 | [& args] 23 | (prn [:foo-server args])) -------------------------------------------------------------------------------- /test/cjs/a-compiled.js: -------------------------------------------------------------------------------- 1 | shadow.js.provide("module$test$cjs$a",function(c,a,d,b){console.log(a("module$test$cjs$d"))}) 2 | //# sourceMappingURL=data:application/json;charset=utf-8;base64,ewoidmVyc2lvbiI6MywKImZpbGUiOiJtb2R1bGUkdGVzdCRjanMkYS5qcyIsCiJsaW5lQ291bnQiOjEsCiJtYXBwaW5ncyI6IkFBQUFBLE1BQUFDLEdBQUFDLFFBQUEsQ0FBa0IsbUJBQWxCLENBQXVDLFFBQVEsQ0FBQ0MsQ0FBRCxDQUFRQyxDQUFSLENBQWdCQyxDQUFoQixDQUF1QkMsQ0FBdkIsQ0FBZ0MsQ0FJL0VDLE9BQUFDLElBQUEsQ0FBWUosQ0FBQSxDQUFRLG1CQUFSLENBQVosQ0FKK0UsQ0FBL0U7IiwKInNvdXJjZXMiOlsidGVzdC9janMvYS5qcyJdLAoic291cmNlc0NvbnRlbnQiOlsic2hhZG93LmpzLnByb3ZpZGUoXCJtb2R1bGUkdGVzdCRjanMkYVwiLCBmdW5jdGlvbihnbG9iYWwscmVxdWlyZSxtb2R1bGUsZXhwb3J0cykge1xuaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WID09IFwiZGV2ZWxvcG1lbnRcIikge1xuICBjb25zb2xlLmxvZyhyZXF1aXJlKFwiLi9iXCIpKTtcbn1cbmNvbnNvbGUubG9nKHJlcXVpcmUoXCIuL2RcIikpO1xufSk7Il0sCiJuYW1lcyI6WyJzaGFkb3ciLCJqcyIsInByb3ZpZGUiLCJnbG9iYWwiLCJyZXF1aXJlIiwibW9kdWxlIiwiZXhwb3J0cyIsImNvbnNvbGUiLCJsb2ciXQp9Cg== 3 | -------------------------------------------------------------------------------- /test/cjs/a.js: -------------------------------------------------------------------------------- 1 | if (process.env.NODE_ENV == "development") { 2 | console.log(require("./b")); 3 | } 4 | var d = require("./d"); 5 | console.log("d", d); 6 | module.exports = d; -------------------------------------------------------------------------------- /test/cjs/b.js: -------------------------------------------------------------------------------- 1 | exports = require("./c"); -------------------------------------------------------------------------------- /test/cjs/c.js: -------------------------------------------------------------------------------- 1 | exports = require("./d"); -------------------------------------------------------------------------------- /test/cjs/d.js: -------------------------------------------------------------------------------- 1 | module.exports = "d"; -------------------------------------------------------------------------------- /test/cjs/entry.js: -------------------------------------------------------------------------------- 1 | var demo = require("goog:demo.lib"); 2 | 3 | require("./ignored.css"); 4 | console.log(demo.hello()); 5 | 6 | -------------------------------------------------------------------------------- /test/cjs/js-sm-test.js: -------------------------------------------------------------------------------- 1 | console.log("js-sm-test"); 2 | 3 | module.exports = require("./a"); -------------------------------------------------------------------------------- /test/closure-inputs/assigns.js: -------------------------------------------------------------------------------- 1 | var X = exports.X = function () { 2 | this.a = 1; 3 | }; 4 | 5 | X.prototype.b = function() { 6 | return this.a; 7 | } 8 | 9 | var local = 3; 10 | 11 | exports.X = X; 12 | exports.c = 1; 13 | 14 | exports.d = { 15 | e: 2, 16 | "f": 3 17 | }; 18 | 19 | 20 | var g = { h: {} }; 21 | 22 | g.h.j = 1; 23 | 24 | Object.defineProperty(g, "thing", {}); -------------------------------------------------------------------------------- /test/closure-inputs/dummy.js: -------------------------------------------------------------------------------- 1 | var x = 1; 2 | //# sourceMappingURL=dummy.js.map 3 | -------------------------------------------------------------------------------- /test/closure-inputs/dummy.js.map: -------------------------------------------------------------------------------- 1 | {} -------------------------------------------------------------------------------- /test/closure-inputs/node_env.js: -------------------------------------------------------------------------------- 1 | if (process.env.NODE_ENV == 'production') { 2 | "EQ:prod" 3 | } else { 4 | "EQ:dev" 5 | } 6 | 7 | if (process.env.NODE_ENV) { 8 | "check"; 9 | } 10 | 11 | if (something == "foo") "something"; 12 | 13 | if (process.env.NODE_ENV == 'development') { 14 | "EQ:dev" 15 | } else { 16 | "EQ:prod" 17 | } 18 | 19 | if (process.env.NODE_ENV == "production") { 20 | "EQ;prod;no-else" 21 | } 22 | 23 | if (process.env.NODE_ENV === "production") { 24 | "SHEQ;prod;no-else" 25 | } 26 | 27 | if (process.env.NODE_ENV == "development") { 28 | "removed"; 29 | } 30 | 31 | if (process.env.NODE_ENV != "development") { 32 | "NE;prod"; 33 | } 34 | 35 | if (process.env.NODE_ENV !== "development") { 36 | "SHNE;prod"; 37 | } 38 | 39 | 40 | 41 | var test2 = (process.env.NODE_ENV !== "production") ? "dev" : "prod"; 42 | 43 | process.env.NODE_ENV !== "production" ? warning(false, "`valueLink` prop on `input` is deprecated; set `value` and `onChange` instead.") : void 0; 44 | 45 | if (/[?&]react_perf\b/.test(url)) { 46 | ReactDebugTool.beginProfiling(); 47 | } 48 | 49 | var x = Buffer(); 50 | 51 | console.log(__dirname); 52 | console.log(__filename); -------------------------------------------------------------------------------- /test/dummy/circular-a.js: -------------------------------------------------------------------------------- 1 | 2 | exports.test = function() { 3 | return "hello world"; 4 | } 5 | 6 | exports.foo = function() { 7 | return require("./circular-b").foo(); 8 | } -------------------------------------------------------------------------------- /test/dummy/circular-b.js: -------------------------------------------------------------------------------- 1 | 2 | exports.foo = function() { 3 | return require("./circular-a").test(); 4 | }; -------------------------------------------------------------------------------- /test/dummy/react.dev.js: -------------------------------------------------------------------------------- 1 | var React = "dev.react"; -------------------------------------------------------------------------------- /test/dummy/react.min.js: -------------------------------------------------------------------------------- 1 | var React = "min.react"; -------------------------------------------------------------------------------- /test/es6/babel.js: -------------------------------------------------------------------------------- 1 | 2 | import Something, { Foo } from "./thing"; 3 | 4 | const PI = 3.141593 5 | 6 | class Shape { 7 | constructor (id, x, y) { 8 | this.id = id 9 | this.move(x, y) 10 | } 11 | move (x, y) { 12 | this.x = x 13 | this.y = y 14 | } 15 | } 16 | 17 | console.log("babel.js", new Shape("test", 1, 2)); 18 | 19 | // works but needs externs or exports in :advanced 20 | // import * as str from "goog:goog.string"; 21 | 22 | export { PI, Something, Foo }; 23 | 24 | export default Shape; 25 | 26 | /* 27 | // needs regenerator runtime, whatever that is 28 | function loadExternalContent() { 29 | return new Promise((resolve, reject) => { 30 | setTimeout(() => { 31 | resolve('hello'); 32 | }, 3000); 33 | }); 34 | } 35 | async function getContent() { 36 | const text = await loadExternalContent(); 37 | console.log(text); 38 | } 39 | */ -------------------------------------------------------------------------------- /test/es6/polyfill.js: -------------------------------------------------------------------------------- 1 | // ES6 things that require polyfills 2 | 3 | 4 | // https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Promise 5 | 6 | function myAsyncFunction(url) { 7 | return new Promise((resolve, reject) => { 8 | const xhr = new XMLHttpRequest(); 9 | xhr.open("GET", url); 10 | xhr.onload = () => resolve(xhr.responseText); 11 | xhr.onerror = () => reject(xhr.statusText); 12 | xhr.send(); 13 | }); 14 | }; 15 | 16 | myAsyncFunction("http://www.clojurescript.org").then(function(res) { console.log(res); }) 17 | 18 | 19 | var x = new Map(); 20 | 21 | console.log("x", x); 22 | 23 | var y = new Set(); 24 | 25 | console.log("y", y); 26 | 27 | 28 | /** @constructor */ 29 | var a = function() { 30 | this.foo = true; 31 | } 32 | 33 | console.log(new a()); 34 | 35 | 36 | export { x, y, myAsyncFunction as z }; 37 | -------------------------------------------------------------------------------- /test/es6/thing.js: -------------------------------------------------------------------------------- 1 | 2 | export let Foo = "Foo"; 3 | export default "Something"; -------------------------------------------------------------------------------- /test/resource-dir/deps.cljs: -------------------------------------------------------------------------------- 1 | {:externs 2 | ["foo/externs.js"] 3 | 4 | :foreign-libs 5 | [{:file "file.js" 6 | :file-min "file-min.js" 7 | :externs ["file-externs.js"] 8 | :provides ["file"]}]} 9 | -------------------------------------------------------------------------------- /test/resource-dir/file-externs.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thheller/shadow-cljs/efd77b59a1f89a6c877e8471c26f127095271ec5/test/resource-dir/file-externs.js -------------------------------------------------------------------------------- /test/resource-dir/file-min.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thheller/shadow-cljs/efd77b59a1f89a6c877e8471c26f127095271ec5/test/resource-dir/file-min.js -------------------------------------------------------------------------------- /test/resource-dir/file.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thheller/shadow-cljs/efd77b59a1f89a6c877e8471c26f127095271ec5/test/resource-dir/file.js -------------------------------------------------------------------------------- /test/resource-dir/foo/bar.cljs: -------------------------------------------------------------------------------- 1 | (ns foo.bar) 2 | -------------------------------------------------------------------------------- /test/resource-dir/foo/es6.js: -------------------------------------------------------------------------------- 1 | import "goog:foo.goog"; -------------------------------------------------------------------------------- /test/resource-dir/foo/externs.js: -------------------------------------------------------------------------------- 1 | /** @externs */ -------------------------------------------------------------------------------- /test/resource-dir/foo/goog.js: -------------------------------------------------------------------------------- 1 | goog.provide("foo.goog"); 2 | 3 | foo.goog.bar = true; --------------------------------------------------------------------------------