@decohere/flux 0.0.1-dev.11 → 0.0.1-dev.110

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/README.md +247 -0
  2. package/commonjs/src/deferred-script-runner.js +56 -0
  3. package/commonjs/src/flux.command.js +2 -2
  4. package/commonjs/src/flux.js +56 -0
  5. package/commonjs/src/flux.module.js +8 -7
  6. package/commonjs/src/hot-reload-server.js +302 -215
  7. package/commonjs/src/index.js +34 -2
  8. package/commonjs/src/rewrite-serve-specifier.js +59 -0
  9. package/commonjs/src/run.action.js +47 -0
  10. package/commonjs/src/run.command.js +65 -0
  11. package/commonjs/src/serve.action.js +76 -5
  12. package/commonjs/src/serve.command.js +31 -3
  13. package/commonjs/src/slice-serve.js +130 -0
  14. package/commonjs/src/source-module-loader.js +237 -0
  15. package/es6/src/deferred-script-runner.js +46 -0
  16. package/es6/src/flux.command.js +2 -2
  17. package/es6/src/flux.js +41 -0
  18. package/es6/src/flux.module.js +8 -7
  19. package/es6/src/hot-reload-server.js +283 -172
  20. package/es6/src/index.js +5 -3
  21. package/es6/src/rewrite-serve-specifier.js +49 -0
  22. package/es6/src/run.action.js +37 -0
  23. package/es6/src/run.command.js +55 -0
  24. package/es6/src/serve.action.js +71 -7
  25. package/es6/src/serve.command.js +31 -3
  26. package/es6/src/slice-serve.js +105 -0
  27. package/es6/src/source-module-loader.js +181 -0
  28. package/package.json +7 -6
  29. package/types/src/deferred-script-runner.d.ts +18 -0
  30. package/types/src/flux.d.ts +43 -0
  31. package/types/src/flux.module.d.ts +2 -0
  32. package/types/src/hot-reload-server.d.ts +55 -22
  33. package/types/src/index.d.ts +8 -1
  34. package/types/src/rewrite-serve-specifier.d.ts +14 -0
  35. package/types/src/run.action.d.ts +15 -0
  36. package/types/src/run.command.d.ts +11 -0
  37. package/types/src/serve.action.d.ts +11 -1
  38. package/types/src/serve.command.d.ts +5 -0
  39. package/types/src/slice-serve.d.ts +52 -0
  40. package/types/src/source-module-loader.d.ts +58 -0
@@ -9,14 +9,46 @@ function _export(target, all) {
9
9
  });
10
10
  }
11
11
  _export(exports, {
12
+ get DEFAULT_REBOOT_DEBOUNCE_MS () {
13
+ return _hotreloadserver.DEFAULT_REBOOT_DEBOUNCE_MS;
14
+ },
15
+ get DeferredScriptRunner () {
16
+ return _deferredscriptrunner.DeferredScriptRunner;
17
+ },
12
18
  get FluxModule () {
13
19
  return _fluxmodule.FluxModule;
14
20
  },
15
21
  get HotReloadServer () {
16
22
  return _hotreloadserver.HotReloadServer;
23
+ },
24
+ get SourceModuleLoader () {
25
+ return _sourcemoduleloader.SourceModuleLoader;
26
+ },
27
+ get classifySliceProject () {
28
+ return _sliceserve.classifySliceProject;
29
+ },
30
+ get classifySliceProjects () {
31
+ return _sliceserve.classifySliceProjects;
32
+ },
33
+ get flux () {
34
+ return _flux.flux;
35
+ },
36
+ get normalizeSlicePrefix () {
37
+ return _sliceserve.normalizeSlicePrefix;
38
+ },
39
+ get projectsInSlice () {
40
+ return _sliceserve.projectsInSlice;
41
+ },
42
+ get projectsInSlices () {
43
+ return _sliceserve.projectsInSlices;
44
+ },
45
+ get resolveDeferScript () {
46
+ return _sliceserve.resolveDeferScript;
17
47
  }
18
48
  });
49
+ const _deferredscriptrunner = require("./deferred-script-runner.js");
50
+ const _flux = require("./flux.js");
19
51
  const _fluxmodule = require("./flux.module.js");
20
52
  const _hotreloadserver = require("./hot-reload-server.js");
21
-
22
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi9ob21lL3J1bm5lci93b3JrL2RlY29oZXJlL2RlY29oZXJlL3Byb2plY3RzL2ZsdXgvc3JjL2luZGV4LnRzIl0sInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCB7IEZsdXhNb2R1bGUgfSBmcm9tIFwiLi9mbHV4Lm1vZHVsZS5qc1wiO1xuZXhwb3J0IHR5cGUgeyBIb3RSZWxvYWRTZXJ2ZXJPcHRpb25zIH0gZnJvbSBcIi4vaG90LXJlbG9hZC1zZXJ2ZXIuanNcIjtcbmV4cG9ydCB7IEhvdFJlbG9hZFNlcnZlciB9IGZyb20gXCIuL2hvdC1yZWxvYWQtc2VydmVyLmpzXCI7XG5leHBvcnQgdHlwZSB7IFNlcnZlT3B0aW9ucyB9IGZyb20gXCIuL3NlcnZlLmFjdGlvbi5qc1wiO1xuIl0sIm5hbWVzIjpbIkZsdXhNb2R1bGUiLCJIb3RSZWxvYWRTZXJ2ZXIiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7O1FBQVNBO2VBQUFBLHNCQUFVOztRQUVWQztlQUFBQSxnQ0FBZTs7OzRCQUZHO2lDQUVLIn0=
53
+ const _sliceserve = require("./slice-serve.js");
54
+ const _sourcemoduleloader = require("./source-module-loader.js");
@@ -0,0 +1,59 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ Object.defineProperty(exports, "rewriteServeSpecifier", {
6
+ enumerable: true,
7
+ get: function() {
8
+ return rewriteServeSpecifier;
9
+ }
10
+ });
11
+ const _nodepath = /*#__PURE__*/ _interop_require_default(require("node:path"));
12
+ const _nodeurl = require("node:url");
13
+ const _mesh = require("@decohere/mesh");
14
+ function _interop_require_default(obj) {
15
+ return obj && obj.__esModule ? obj : {
16
+ default: obj
17
+ };
18
+ }
19
+ function rewriteServeSpecifier(options) {
20
+ const { specifier, parentUrl, isWatchedTs, resolveBare, versionFileUrl } = options;
21
+ const relativeTs = resolveRelativeWatchedTs(specifier, parentUrl, isWatchedTs);
22
+ if (relativeTs != null) {
23
+ return versionFileUrl((0, _nodeurl.pathToFileURL)(relativeTs).toString());
24
+ }
25
+ const bareTarget = resolveBare(specifier);
26
+ const bareTs = bareTarget == null ? null : watchedTs(bareTarget, isWatchedTs);
27
+ if (bareTs != null) {
28
+ return versionFileUrl((0, _nodeurl.pathToFileURL)(bareTs).toString());
29
+ }
30
+ return null;
31
+ }
32
+ /**
33
+ * The watched `.ts` file a path names: itself (with `.js` read as `.ts`, or `.ts` added), else
34
+ * the `index.ts` of the directory it names. A file wins over a directory of the same name.
35
+ */ function watchedTs(filePath, isWatchedTs) {
36
+ const withoutSlash = filePath.replace(/[/\\]+$/, "");
37
+ const stem = withoutSlash.replace(/\.(js|ts)$/, "");
38
+ // From the stem: Mesh's alias lookup has already added `.ts` to a subpath that names a
39
+ // directory (`@lib/models` arrives as `…/models.ts`).
40
+ const candidates = [
41
+ `${stem}.ts`,
42
+ _nodepath.default.join(stem, "index.ts")
43
+ ];
44
+ return candidates.find((candidate)=>isWatchedTs(candidate)) ?? null;
45
+ }
46
+ function resolveRelativeWatchedTs(specifier, parentUrl, isWatchedTs) {
47
+ if (_mesh.packageAliases.isBareSpecifier(specifier)) return null;
48
+ if (!(specifier.startsWith(".") || specifier.startsWith("/"))) return null;
49
+ const parentClean = parentUrl.split("?")[0];
50
+ if (parentClean == null || parentClean === "") return null;
51
+ let resolved;
52
+ try {
53
+ resolved = new URL(specifier, parentClean);
54
+ } catch {
55
+ return null;
56
+ }
57
+ if (resolved.protocol !== "file:") return null;
58
+ return watchedTs((0, _nodeurl.fileURLToPath)(resolved), isWatchedTs);
59
+ }
@@ -0,0 +1,47 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ Object.defineProperty(exports, "RunAction", {
6
+ enumerable: true,
7
+ get: function() {
8
+ return RunAction;
9
+ }
10
+ });
11
+ const _decorators = require("@decohere/crucible/decorators");
12
+ const _mesh = require("@decohere/mesh");
13
+ const _cli = require("@decohere/nexus/cli");
14
+ const _scribe = require("@decohere/scribe");
15
+ const _flux = require("./flux.js");
16
+ function _ts_decorate(decorators, target, key, desc) {
17
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
18
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
19
+ else for(var i = decorators.length - 1; i >= 0; i--)if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
20
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
21
+ }
22
+ function _ts_metadata(k, v) {
23
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
24
+ }
25
+ class RunAction {
26
+ workspace;
27
+ logger = _scribe.scribe.logger(RunAction.name);
28
+ constructor(workspace){
29
+ this.workspace = workspace;
30
+ }
31
+ async run(options) {
32
+ this.logger.trace(`Running ${options.entry}`);
33
+ await _flux.flux.run(options.entry, {
34
+ configuration: options.configuration,
35
+ args: options.args,
36
+ workspace: this.workspace
37
+ });
38
+ return _cli.ActionResponse.Success(RunAction.name);
39
+ }
40
+ }
41
+ RunAction = _ts_decorate([
42
+ (0, _decorators.injectable)(),
43
+ _ts_metadata("design:type", Function),
44
+ _ts_metadata("design:paramtypes", [
45
+ typeof _mesh.Workspace === "undefined" ? Object : _mesh.Workspace
46
+ ])
47
+ ], RunAction);
@@ -0,0 +1,65 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ Object.defineProperty(exports, "RunCommand", {
6
+ enumerable: true,
7
+ get: function() {
8
+ return RunCommand;
9
+ }
10
+ });
11
+ const _cli = require("@decohere/nexus/cli");
12
+ const _runaction = require("./run.action.js");
13
+ class RunCommand extends _cli.DecohereCommand {
14
+ get actions() {
15
+ return [
16
+ _runaction.RunAction
17
+ ];
18
+ }
19
+ constructor(name){
20
+ super(name);
21
+ this.description("Compile and run a TypeScript entry on the fly (no watch / HMR)");
22
+ this.argument("<entry>", "Path to the TypeScript entry file");
23
+ this.argument("[args...]", "Arguments forwarded to the entry after rewriting argv");
24
+ this.addOption(new _cli.ConfigurationOption("debug"));
25
+ }
26
+ /**
27
+ * Commander passes positionals before options when `<entry> [args...]` is declared.
28
+ * The CLI host ModuleFactory expects `(opts, cmd)` — normalize and stash entry/args on opts.
29
+ */ action(fn) {
30
+ return super.action((...args)=>{
31
+ const cmd = args.at(-1);
32
+ const opts = args.at(-2);
33
+ const { entry, entryArgs } = normalizeRunPositionals(args.slice(0, -2));
34
+ cmd.setOptionValue("entry", entry);
35
+ cmd.setOptionValue("args", entryArgs);
36
+ return fn(opts, cmd);
37
+ });
38
+ }
39
+ }
40
+ /** Commander yields `[entry, args[]]` or sometimes a flat list depending on arity. */ function normalizeRunPositionals(positionals) {
41
+ if (positionals.length === 0) {
42
+ return {
43
+ entry: "",
44
+ entryArgs: []
45
+ };
46
+ }
47
+ const first = positionals[0];
48
+ if (typeof first !== "string" || first === "") {
49
+ return {
50
+ entry: "",
51
+ entryArgs: []
52
+ };
53
+ }
54
+ const second = positionals[1];
55
+ if (Array.isArray(second)) {
56
+ return {
57
+ entry: first,
58
+ entryArgs: second.filter((s)=>typeof s === "string")
59
+ };
60
+ }
61
+ return {
62
+ entry: first,
63
+ entryArgs: positionals.slice(1).filter((s)=>typeof s === "string" && s !== "")
64
+ };
65
+ }
@@ -8,10 +8,19 @@ Object.defineProperty(exports, "ServeAction", {
8
8
  return ServeAction;
9
9
  }
10
10
  });
11
+ const _nodepath = /*#__PURE__*/ _interop_require_default(require("node:path"));
11
12
  const _decorators = require("@decohere/crucible/decorators");
12
13
  const _mesh = require("@decohere/mesh");
13
14
  const _cli = require("@decohere/nexus/cli");
15
+ const _scribe = require("@decohere/scribe");
16
+ const _deferredscriptrunner = require("./deferred-script-runner.js");
14
17
  const _hotreloadserver = require("./hot-reload-server.js");
18
+ const _sliceserve = require("./slice-serve.js");
19
+ function _interop_require_default(obj) {
20
+ return obj && obj.__esModule ? obj : {
21
+ default: obj
22
+ };
23
+ }
15
24
  function _ts_decorate(decorators, target, key, desc) {
16
25
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
17
26
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
@@ -24,26 +33,88 @@ function _ts_metadata(k, v) {
24
33
  class ServeAction {
25
34
  server;
26
35
  workspace;
27
- constructor(server, workspace){
36
+ deferredScripts;
37
+ logger = _scribe.scribe.logger(ServeAction.name);
38
+ constructor(server, workspace, deferredScripts){
28
39
  this.server = server;
29
40
  this.workspace = workspace;
41
+ this.deferredScripts = deferredScripts;
30
42
  }
31
43
  async run(options) {
44
+ const slices = (options.slices ?? []).filter((s)=>s !== "");
45
+ if (slices.length > 0 && options.project != null) {
46
+ throw new Error("Use either directory slices or --project, not both");
47
+ }
48
+ if (slices.length > 0) {
49
+ return this.runSlices(options, slices);
50
+ }
32
51
  await this.server.start({
33
52
  workspace: this.workspace,
34
53
  buildConfig: options.configuration,
35
- project: options.project
54
+ project: options.project,
55
+ rebootDebounceMs: options.rebootDebounceMs
36
56
  });
37
57
  return _cli.ActionResponse.Blocking(ServeAction.name);
38
58
  }
59
+ async runSlices(options, slices) {
60
+ const views = await this.toSliceViews(options.configuration);
61
+ const classified = (0, _sliceserve.classifySliceProjects)(views, slices);
62
+ const label = slices.join(" ");
63
+ for (const skipped of classified.skip){
64
+ this.logger.info(`skipped ${skipped.projectDirectory} — library (no Flux entry / scripts)`);
65
+ }
66
+ if (classified.flux.length === 0 && classified.defer.length === 0) {
67
+ throw new Error(`No runnable projects in slice(s) "${label}" (need Flux main.ts apps and/or package scripts.dev/serve)`);
68
+ }
69
+ const workspaceRoot = _nodepath.default.resolve(this.workspace.rootDir ?? process.cwd());
70
+ for (const deferred of classified.defer){
71
+ const script = (0, _sliceserve.resolveDeferScript)(deferred.scripts);
72
+ if (script == null) continue;
73
+ const project = this.findProject(options.configuration, deferred.name);
74
+ this.deferredScripts.start({
75
+ label: deferred.projectDirectory,
76
+ cwd: project.projectRoot,
77
+ script,
78
+ workspaceRoot
79
+ });
80
+ }
81
+ if (classified.flux.length > 0) {
82
+ await this.server.start({
83
+ workspace: this.workspace,
84
+ buildConfig: options.configuration,
85
+ projects: classified.flux.map((p)=>p.name),
86
+ rebootDebounceMs: options.rebootDebounceMs
87
+ });
88
+ }
89
+ return _cli.ActionResponse.Blocking(ServeAction.name);
90
+ }
91
+ async toSliceViews(configuration) {
92
+ const projects = this.workspace.getProjects(configuration);
93
+ return Promise.all(projects.map((project)=>this.toSliceView(project)));
94
+ }
95
+ async toSliceView(project) {
96
+ const pkg = await project.getPackageJson();
97
+ return {
98
+ name: project.name,
99
+ projectDirectory: project.projectDirectory.replaceAll("\\", "/"),
100
+ main: pkg.main ?? "src/index.ts",
101
+ scripts: pkg.scripts ?? {}
102
+ };
103
+ }
104
+ findProject(configuration, name) {
105
+ const found = this.workspace.getProjects(configuration).find((p)=>p.name === name);
106
+ if (found == null) {
107
+ throw new Error(`Project "${name}" not found in workspace`);
108
+ }
109
+ return found;
110
+ }
39
111
  }
40
112
  ServeAction = _ts_decorate([
41
113
  (0, _decorators.injectable)(),
42
114
  _ts_metadata("design:type", Function),
43
115
  _ts_metadata("design:paramtypes", [
44
116
  typeof _hotreloadserver.HotReloadServer === "undefined" ? Object : _hotreloadserver.HotReloadServer,
45
- typeof _mesh.Workspace === "undefined" ? Object : _mesh.Workspace
117
+ typeof _mesh.Workspace === "undefined" ? Object : _mesh.Workspace,
118
+ typeof _deferredscriptrunner.DeferredScriptRunner === "undefined" ? Object : _deferredscriptrunner.DeferredScriptRunner
46
119
  ])
47
120
  ], ServeAction);
48
-
49
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi9ob21lL3J1bm5lci93b3JrL2RlY29oZXJlL2RlY29oZXJlL3Byb2plY3RzL2ZsdXgvc3JjL3NlcnZlLmFjdGlvbi50cyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBpbmplY3RhYmxlIH0gZnJvbSBcIkBkZWNvaGVyZS9jcnVjaWJsZS9kZWNvcmF0b3JzXCI7XG4vLyBiaW9tZS1pZ25vcmUgbGludC9zdHlsZS91c2VJbXBvcnRUeXBlOiA8REk+XG5pbXBvcnQgeyBXb3Jrc3BhY2UgfSBmcm9tIFwiQGRlY29oZXJlL21lc2hcIjtcbmltcG9ydCB7IHR5cGUgQWN0aW9uLCBBY3Rpb25SZXNwb25zZSB9IGZyb20gXCJAZGVjb2hlcmUvbmV4dXMvY2xpXCI7XG4vLyBiaW9tZS1pZ25vcmUgbGludC9zdHlsZS91c2VJbXBvcnRUeXBlOiA8REk+XG5pbXBvcnQgeyBIb3RSZWxvYWRTZXJ2ZXIgfSBmcm9tIFwiLi9ob3QtcmVsb2FkLXNlcnZlci5qc1wiO1xuXG5leHBvcnQgdHlwZSBTZXJ2ZU9wdGlvbnMgPSB7XG5cdGNvbmZpZ3VyYXRpb246IHN0cmluZztcblx0cHJvamVjdD86IHN0cmluZztcbn07XG5cbkBpbmplY3RhYmxlKClcbmV4cG9ydCBjbGFzcyBTZXJ2ZUFjdGlvbiBpbXBsZW1lbnRzIEFjdGlvbjxTZXJ2ZU9wdGlvbnM+IHtcblx0cHVibGljIGNvbnN0cnVjdG9yKFxuXHRcdHByaXZhdGUgcmVhZG9ubHkgc2VydmVyOiBIb3RSZWxvYWRTZXJ2ZXIsXG5cdFx0cHJpdmF0ZSByZWFkb25seSB3b3Jrc3BhY2U6IFdvcmtzcGFjZSxcblx0KSB7fVxuXG5cdHB1YmxpYyBhc3luYyBydW4ob3B0aW9uczogU2VydmVPcHRpb25zKTogUHJvbWlzZTxBY3Rpb25SZXNwb25zZT4ge1xuXHRcdGF3YWl0IHRoaXMuc2VydmVyLnN0YXJ0KHtcblx0XHRcdHdvcmtzcGFjZTogdGhpcy53b3Jrc3BhY2UsXG5cdFx0XHRidWlsZENvbmZpZzogb3B0aW9ucy5jb25maWd1cmF0aW9uLFxuXHRcdFx0cHJvamVjdDogb3B0aW9ucy5wcm9qZWN0LFxuXHRcdH0pO1xuXHRcdHJldHVybiBBY3Rpb25SZXNwb25zZS5CbG9ja2luZyhTZXJ2ZUFjdGlvbi5uYW1lKTtcblx0fVxufVxuIl0sIm5hbWVzIjpbIlNlcnZlQWN0aW9uIiwic2VydmVyIiwid29ya3NwYWNlIiwicnVuIiwib3B0aW9ucyIsInN0YXJ0IiwiYnVpbGRDb25maWciLCJjb25maWd1cmF0aW9uIiwicHJvamVjdCIsIkFjdGlvblJlc3BvbnNlIiwiQmxvY2tpbmciLCJuYW1lIl0sIm1hcHBpbmdzIjoiOzs7OytCQWFhQTs7O2VBQUFBOzs7NEJBYmM7c0JBRUQ7cUJBQ2tCO2lDQUVaOzs7Ozs7Ozs7O0FBUXpCLE1BQU1BOzs7SUFDWixZQUNDLEFBQWlCQyxNQUF1QixFQUN4QyxBQUFpQkMsU0FBb0IsQ0FDcEM7YUFGZ0JELFNBQUFBO2FBQ0FDLFlBQUFBO0lBQ2Y7SUFFSCxNQUFhQyxJQUFJQyxPQUFxQixFQUEyQjtRQUNoRSxNQUFNLElBQUksQ0FBQ0gsTUFBTSxDQUFDSSxLQUFLLENBQUM7WUFDdkJILFdBQVcsSUFBSSxDQUFDQSxTQUFTO1lBQ3pCSSxhQUFhRixRQUFRRyxhQUFhO1lBQ2xDQyxTQUFTSixRQUFRSSxPQUFPO1FBQ3pCO1FBQ0EsT0FBT0MsbUJBQWMsQ0FBQ0MsUUFBUSxDQUFDVixZQUFZVyxJQUFJO0lBQ2hEO0FBQ0QifQ==
@@ -9,6 +9,7 @@ Object.defineProperty(exports, "ServeCommand", {
9
9
  }
10
10
  });
11
11
  const _cli = require("@decohere/nexus/cli");
12
+ const _hotreloadserver = require("./hot-reload-server.js");
12
13
  const _serveaction = require("./serve.action.js");
13
14
  class ServeCommand extends _cli.DecohereCommand {
14
15
  get actions() {
@@ -18,10 +19,37 @@ class ServeCommand extends _cli.DecohereCommand {
18
19
  }
19
20
  constructor(name){
20
21
  super(name);
21
- this.description("Serve a project in a workspace configuration");
22
+ this.description("Serve a project or directory slices (Flux apps in-process; foreign packages via package scripts)");
23
+ this.argument("[slices...]", "Module directories to serve (e.g. funding shell secmaster, or projects/funding)");
22
24
  this.addOption(new _cli.ConfigurationOption("debug"));
23
25
  this.addOption(new _cli.ProjectOption());
26
+ this.option("--reboot-debounce-ms <ms>", "Quiet window in milliseconds after the last affecting save before a reboot", (value)=>(0, _hotreloadserver.resolveRebootDebounceMs)(Number(value)), _hotreloadserver.DEFAULT_REBOOT_DEBOUNCE_MS);
24
27
  }
28
+ /**
29
+ * Commander passes positional args before options when `[slices...]` is declared.
30
+ * The CLI host ModuleFactory expects `(opts, cmd)` — normalize here.
31
+ */ action(fn) {
32
+ return super.action((...args)=>{
33
+ const cmd = args.at(-1);
34
+ const first = args[0];
35
+ const hasPositionalSlices = Array.isArray(first) || typeof first === "string" || first === undefined;
36
+ const opts = hasPositionalSlices ? args[1] : args[0];
37
+ const slices = normalizePositionalSlices(first);
38
+ if (slices.length > 0) {
39
+ cmd.setOptionValue("slices", slices);
40
+ }
41
+ return fn(opts, cmd);
42
+ });
43
+ }
44
+ }
45
+ function normalizePositionalSlices(first) {
46
+ if (Array.isArray(first)) {
47
+ return first.filter((s)=>typeof s === "string" && s !== "");
48
+ }
49
+ if (typeof first === "string" && first !== "") {
50
+ return [
51
+ first
52
+ ];
53
+ }
54
+ return [];
25
55
  }
26
-
27
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi9ob21lL3J1bm5lci93b3JrL2RlY29oZXJlL2RlY29oZXJlL3Byb2plY3RzL2ZsdXgvc3JjL3NlcnZlLmNvbW1hbmQudHMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29uZmlndXJhdGlvbk9wdGlvbiwgRGVjb2hlcmVDb21tYW5kLCBQcm9qZWN0T3B0aW9uIH0gZnJvbSBcIkBkZWNvaGVyZS9uZXh1cy9jbGlcIjtcbmltcG9ydCB7IFNlcnZlQWN0aW9uIH0gZnJvbSBcIi4vc2VydmUuYWN0aW9uLmpzXCI7XG5cbmV4cG9ydCBjbGFzcyBTZXJ2ZUNvbW1hbmQgZXh0ZW5kcyBEZWNvaGVyZUNvbW1hbmQge1xuXHRwdWJsaWMgb3ZlcnJpZGUgZ2V0IGFjdGlvbnMoKSB7XG5cdFx0cmV0dXJuIFtTZXJ2ZUFjdGlvbl07XG5cdH1cblxuXHRwdWJsaWMgY29uc3RydWN0b3IobmFtZTogc3RyaW5nKSB7XG5cdFx0c3VwZXIobmFtZSk7XG5cdFx0dGhpcy5kZXNjcmlwdGlvbihcIlNlcnZlIGEgcHJvamVjdCBpbiBhIHdvcmtzcGFjZSBjb25maWd1cmF0aW9uXCIpO1xuXHRcdHRoaXMuYWRkT3B0aW9uKG5ldyBDb25maWd1cmF0aW9uT3B0aW9uKFwiZGVidWdcIikpO1xuXHRcdHRoaXMuYWRkT3B0aW9uKG5ldyBQcm9qZWN0T3B0aW9uKCkpO1xuXHR9XG59XG4iXSwibmFtZXMiOlsiU2VydmVDb21tYW5kIiwiRGVjb2hlcmVDb21tYW5kIiwiYWN0aW9ucyIsIlNlcnZlQWN0aW9uIiwibmFtZSIsImRlc2NyaXB0aW9uIiwiYWRkT3B0aW9uIiwiQ29uZmlndXJhdGlvbk9wdGlvbiIsIlByb2plY3RPcHRpb24iXSwibWFwcGluZ3MiOiI7Ozs7K0JBR2FBOzs7ZUFBQUE7OztxQkFIdUQ7NkJBQ3hDO0FBRXJCLE1BQU1BLHFCQUFxQkMsb0JBQWU7SUFDaEQsSUFBb0JDLFVBQVU7UUFDN0IsT0FBTztZQUFDQyx3QkFBVztTQUFDO0lBQ3JCO0lBRUEsWUFBbUJDLElBQVksQ0FBRTtRQUNoQyxLQUFLLENBQUNBO1FBQ04sSUFBSSxDQUFDQyxXQUFXLENBQUM7UUFDakIsSUFBSSxDQUFDQyxTQUFTLENBQUMsSUFBSUMsd0JBQW1CLENBQUM7UUFDdkMsSUFBSSxDQUFDRCxTQUFTLENBQUMsSUFBSUUsa0JBQWE7SUFDakM7QUFDRCJ9
@@ -0,0 +1,130 @@
1
+ /**
2
+ * Directory-slice helpers for `flux serve <dir>…` — classify Mesh packages as
3
+ * Flux apps, Nixpacks-style script deferrals, or libraries to skip.
4
+ */ "use strict";
5
+ Object.defineProperty(exports, "__esModule", {
6
+ value: true
7
+ });
8
+ function _export(target, all) {
9
+ for(var name in all)Object.defineProperty(target, name, {
10
+ enumerable: true,
11
+ get: Object.getOwnPropertyDescriptor(all, name).get
12
+ });
13
+ }
14
+ _export(exports, {
15
+ get DEFER_SCRIPT_CANDIDATES () {
16
+ return DEFER_SCRIPT_CANDIDATES;
17
+ },
18
+ get classifySliceProject () {
19
+ return classifySliceProject;
20
+ },
21
+ get classifySliceProjects () {
22
+ return classifySliceProjects;
23
+ },
24
+ get isFluxAppMain () {
25
+ return isFluxAppMain;
26
+ },
27
+ get isFluxOwnedScript () {
28
+ return isFluxOwnedScript;
29
+ },
30
+ get isUnderSlice () {
31
+ return isUnderSlice;
32
+ },
33
+ get normalizeSlicePrefix () {
34
+ return normalizeSlicePrefix;
35
+ },
36
+ get projectsInSlice () {
37
+ return projectsInSlice;
38
+ },
39
+ get projectsInSlices () {
40
+ return projectsInSlices;
41
+ },
42
+ get resolveDeferScript () {
43
+ return resolveDeferScript;
44
+ }
45
+ });
46
+ const DEFER_SCRIPT_CANDIDATES = [
47
+ "dev",
48
+ "serve"
49
+ ];
50
+ function normalizeSlicePrefix(slice) {
51
+ const trimmed = slice.replaceAll("\\", "/").replace(/\/+$/, "");
52
+ if (trimmed === "" || trimmed === ".") {
53
+ throw new Error("Slice directory must be a non-empty path");
54
+ }
55
+ if (trimmed === "projects" || trimmed.startsWith("projects/")) {
56
+ return trimmed;
57
+ }
58
+ return `projects/${trimmed}`;
59
+ }
60
+ function isUnderSlice(projectDirectory, slicePrefix) {
61
+ const dir = projectDirectory.replaceAll("\\", "/").replace(/\/+$/, "");
62
+ const prefix = slicePrefix.replaceAll("\\", "/").replace(/\/+$/, "");
63
+ if (dir === prefix || dir.startsWith(`${prefix}/`)) {
64
+ return true;
65
+ }
66
+ // Flat monorepo packages: projects/<module>.<role>
67
+ return dir.startsWith(`${prefix}.`);
68
+ }
69
+ function projectsInSlice(projects, slice) {
70
+ const prefix = normalizeSlicePrefix(slice);
71
+ return projects.filter((p)=>isUnderSlice(p.projectDirectory, prefix));
72
+ }
73
+ function projectsInSlices(projects, slices) {
74
+ const byName = new Map();
75
+ for (const slice of slices){
76
+ for (const project of projectsInSlice(projects, slice)){
77
+ byName.set(project.name, project);
78
+ }
79
+ }
80
+ return [
81
+ ...byName.values()
82
+ ];
83
+ }
84
+ function isFluxOwnedScript(script) {
85
+ return /\bflux\b/i.test(script);
86
+ }
87
+ function resolveDeferScript(scripts) {
88
+ for (const name of DEFER_SCRIPT_CANDIDATES){
89
+ const body = scripts[name];
90
+ if (body != null && body !== "" && !isFluxOwnedScript(body)) {
91
+ return name;
92
+ }
93
+ }
94
+ return undefined;
95
+ }
96
+ function isFluxAppMain(main) {
97
+ const normalized = main.replaceAll("\\", "/");
98
+ return /(^|\/)main\.tsx?$/.test(normalized);
99
+ }
100
+ function classifySliceProject(project) {
101
+ if (resolveDeferScript(project.scripts) != null) {
102
+ return "defer";
103
+ }
104
+ if (isFluxAppMain(project.main)) {
105
+ return "flux";
106
+ }
107
+ return "skip";
108
+ }
109
+ function classifySliceProjects(projects, slices) {
110
+ const tokens = typeof slices === "string" ? [
111
+ slices
112
+ ] : [
113
+ ...slices
114
+ ];
115
+ const inSlice = projectsInSlices(projects, tokens);
116
+ const flux = [];
117
+ const defer = [];
118
+ const skip = [];
119
+ for (const project of inSlice){
120
+ const kind = classifySliceProject(project);
121
+ if (kind === "flux") flux.push(project);
122
+ else if (kind === "defer") defer.push(project);
123
+ else skip.push(project);
124
+ }
125
+ return {
126
+ flux,
127
+ defer,
128
+ skip
129
+ };
130
+ }