@jujulego/jill 2.0.0-alpha.3 → 2.0.0-alpha.5

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.
@@ -0,0 +1,16 @@
1
+ import yargs from 'yargs';
2
+ import { WorkspaceDepsMode } from '../project';
3
+ declare const _default: yargs.CommandModule<unknown, {
4
+ script: string;
5
+ } & {
6
+ "deps-mode": WorkspaceDepsMode;
7
+ } & {
8
+ private: boolean | undefined;
9
+ } & {
10
+ affected: string | undefined;
11
+ } & {
12
+ "affected-rev-sort": string | undefined;
13
+ } & {
14
+ "affected-rev-fallback": string;
15
+ }>;
16
+ export default _default;
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["commands/each.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,MAAM,OAAO,CAAC;AAI1B,OAAO,EAA6B,iBAAiB,EAAE,MAAM,YAAY,CAAC;;;;;;;;;;;;;;AAM1E,wBA+GG","file":"each.d.ts","sourcesContent":["import { waitForEvent } from '@jujulego/event-tree';\nimport { TaskManager, TaskSet } from '@jujulego/tasks';\nimport ink from 'ink';\nimport yargs from 'yargs';\n\nimport { AffectedFilter, Pipeline, PrivateFilter, ScriptsFilter } from '../filters';\nimport { loadProject, setupInk } from '../middlewares';\nimport { Project, WorkspaceContext, WorkspaceDepsMode } from '../project';\nimport { container, CURRENT, INK_APP, SpinnerService } from '../services';\nimport { Layout, TasksSpinner } from '../ui';\nimport { applyMiddlewares, defineCommand } from '../utils';\n\n// Command\nexport default defineCommand({\n command: 'each <script>',\n describe: 'Run script on many workspaces',\n builder: (yargs) =>\n applyMiddlewares(yargs, [\n setupInk,\n loadProject,\n ])\n // Run options\n .positional('script', { type: 'string', demandOption: true })\n .option('deps-mode', {\n choice: ['all', 'prod', 'none'],\n default: 'all' as WorkspaceDepsMode,\n desc: 'Dependency selection mode:\\n' +\n ' - all = dependencies AND devDependencies\\n' +\n ' - prod = dependencies\\n' +\n ' - none = nothing'\n })\n\n // Filters\n .option('private', {\n type: 'boolean',\n group: 'Filters:',\n desc: 'Print only private workspaces',\n })\n\n // Affected filter\n .option('affected', {\n alias: 'a',\n type: 'string',\n coerce: (rev: string) => rev === '' ? 'master' : rev,\n group: 'Affected:',\n desc: 'Print only affected workspaces towards given git revision. If no revision is given, it will check towards master.\\n' +\n 'Replaces %name by workspace name.',\n })\n .option('affected-rev-sort', {\n type: 'string',\n group: 'Affected:',\n desc: 'Sort applied to git tag / git branch command',\n })\n .option('affected-rev-fallback', {\n type: 'string',\n default: 'master',\n group: 'Affected:',\n desc: 'Fallback revision, used if no revision matching the given format is found',\n }),\n async handler(args) {\n const app = container.get<ink.Instance>(INK_APP);\n const project = container.getNamed(Project, CURRENT);\n const manager = container.get(TaskManager);\n const spinner = container.get(SpinnerService);\n\n try {\n spinner.spin('Loading workspaces ...');\n\n // Setup pipeline\n const pipeline = new Pipeline();\n pipeline.add(new ScriptsFilter([args.script]));\n\n if (args.private !== undefined) {\n pipeline.add(new PrivateFilter(args.private));\n }\n\n if (args.affected !== undefined) {\n pipeline.add(new AffectedFilter(\n args.affected,\n args.affectedRevFallback,\n args.affectedRevSort\n ));\n }\n\n // Extract arguments\n const rest = args._.map(arg => arg.toString());\n\n if (rest[0] === 'each') {\n rest.splice(0, 1);\n }\n\n // Create script tasks\n const tasks = new TaskSet<WorkspaceContext>(manager);\n\n for await (const wks of pipeline.filter(project.workspaces())) {\n tasks.add(await wks.run(args.script, rest, {\n buildDeps: args.depsMode,\n }));\n }\n\n if (tasks.tasks.length === 0) {\n spinner.failed('No workspace found !');\n return yargs.exit(1, new Error('No workspace found !'));\n }\n\n spinner.stop();\n\n // Start and wait for result\n tasks.start();\n app.rerender(\n <Layout>\n <TasksSpinner manager={manager} />\n </Layout>\n );\n\n const result = await waitForEvent(tasks, 'finished');\n\n if (result.failed > 0) {\n return yargs.exit(1, new Error('A tasks failed !'));\n }\n } finally {\n spinner.stop();\n }\n }\n});\n"]}
@@ -0,0 +1,117 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ Object.defineProperty(exports, // Command
6
+ "default", {
7
+ enumerable: true,
8
+ get: ()=>_default
9
+ });
10
+ const _jsxRuntime = require("react/jsx-runtime");
11
+ const _eventTree = require("@jujulego/event-tree");
12
+ const _tasks = require("@jujulego/tasks");
13
+ const _yargs = /*#__PURE__*/ _interopRequireDefault(require("yargs"));
14
+ const _filters = require("../filters");
15
+ const _middlewares = require("../middlewares");
16
+ const _project = require("../project");
17
+ const _services = require("../services");
18
+ const _ui = require("../ui");
19
+ const _utils = require("../utils");
20
+ function _interopRequireDefault(obj) {
21
+ return obj && obj.__esModule ? obj : {
22
+ default: obj
23
+ };
24
+ }
25
+ const _default = (0, _utils.defineCommand)({
26
+ command: 'each <script>',
27
+ describe: 'Run script on many workspaces',
28
+ builder: (yargs)=>(0, _utils.applyMiddlewares)(yargs, [
29
+ _middlewares.setupInk,
30
+ _middlewares.loadProject
31
+ ])// Run options
32
+ .positional('script', {
33
+ type: 'string',
34
+ demandOption: true
35
+ }).option('deps-mode', {
36
+ choice: [
37
+ 'all',
38
+ 'prod',
39
+ 'none'
40
+ ],
41
+ default: 'all',
42
+ desc: 'Dependency selection mode:\n' + ' - all = dependencies AND devDependencies\n' + ' - prod = dependencies\n' + ' - none = nothing'
43
+ })// Filters
44
+ .option('private', {
45
+ type: 'boolean',
46
+ group: 'Filters:',
47
+ desc: 'Print only private workspaces'
48
+ })// Affected filter
49
+ .option('affected', {
50
+ alias: 'a',
51
+ type: 'string',
52
+ coerce: (rev)=>rev === '' ? 'master' : rev,
53
+ group: 'Affected:',
54
+ desc: 'Print only affected workspaces towards given git revision. If no revision is given, it will check towards master.\n' + 'Replaces %name by workspace name.'
55
+ }).option('affected-rev-sort', {
56
+ type: 'string',
57
+ group: 'Affected:',
58
+ desc: 'Sort applied to git tag / git branch command'
59
+ }).option('affected-rev-fallback', {
60
+ type: 'string',
61
+ default: 'master',
62
+ group: 'Affected:',
63
+ desc: 'Fallback revision, used if no revision matching the given format is found'
64
+ }),
65
+ async handler (args) {
66
+ const app = _services.container.get(_services.INK_APP);
67
+ const project = _services.container.getNamed(_project.Project, _services.CURRENT);
68
+ const manager = _services.container.get(_tasks.TaskManager);
69
+ const spinner = _services.container.get(_services.SpinnerService);
70
+ try {
71
+ spinner.spin('Loading workspaces ...');
72
+ // Setup pipeline
73
+ const pipeline = new _filters.Pipeline();
74
+ pipeline.add(new _filters.ScriptsFilter([
75
+ args.script
76
+ ]));
77
+ if (args.private !== undefined) {
78
+ pipeline.add(new _filters.PrivateFilter(args.private));
79
+ }
80
+ if (args.affected !== undefined) {
81
+ pipeline.add(new _filters.AffectedFilter(args.affected, args.affectedRevFallback, args.affectedRevSort));
82
+ }
83
+ // Extract arguments
84
+ const rest = args._.map((arg)=>arg.toString());
85
+ if (rest[0] === 'each') {
86
+ rest.splice(0, 1);
87
+ }
88
+ // Create script tasks
89
+ const tasks = new _tasks.TaskSet(manager);
90
+ for await (const wks of pipeline.filter(project.workspaces())){
91
+ tasks.add(await wks.run(args.script, rest, {
92
+ buildDeps: args.depsMode
93
+ }));
94
+ }
95
+ if (tasks.tasks.length === 0) {
96
+ spinner.failed('No workspace found !');
97
+ return _yargs.default.exit(1, new Error('No workspace found !'));
98
+ }
99
+ spinner.stop();
100
+ // Start and wait for result
101
+ tasks.start();
102
+ app.rerender(/*#__PURE__*/ (0, _jsxRuntime.jsx)(_ui.Layout, {
103
+ children: /*#__PURE__*/ (0, _jsxRuntime.jsx)(_ui.TasksSpinner, {
104
+ manager: manager
105
+ })
106
+ }));
107
+ const result = await (0, _eventTree.waitForEvent)(tasks, 'finished');
108
+ if (result.failed > 0) {
109
+ return _yargs.default.exit(1, new Error('A tasks failed !'));
110
+ }
111
+ } finally{
112
+ spinner.stop();
113
+ }
114
+ }
115
+ });
116
+
117
+ //# sourceMappingURL=each.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["commands/each.js"],"sourcesContent":["import { waitForEvent } from '@jujulego/event-tree';\nimport { TaskManager, TaskSet } from '@jujulego/tasks';\nimport ink from 'ink';\nimport yargs from 'yargs';\n\nimport { AffectedFilter, Pipeline, PrivateFilter, ScriptsFilter } from '../filters';\nimport { loadProject, setupInk } from '../middlewares';\nimport { Project, WorkspaceContext, WorkspaceDepsMode } from '../project';\nimport { container, CURRENT, INK_APP, SpinnerService } from '../services';\nimport { Layout, TasksSpinner } from '../ui';\nimport { applyMiddlewares, defineCommand } from '../utils';\n\n// Command\nexport default defineCommand({\n command: 'each <script>',\n describe: 'Run script on many workspaces',\n builder: (yargs) =>\n applyMiddlewares(yargs, [\n setupInk,\n loadProject,\n ])\n // Run options\n .positional('script', { type: 'string', demandOption: true })\n .option('deps-mode', {\n choice: ['all', 'prod', 'none'],\n default: 'all' as WorkspaceDepsMode,\n desc: 'Dependency selection mode:\\n' +\n ' - all = dependencies AND devDependencies\\n' +\n ' - prod = dependencies\\n' +\n ' - none = nothing'\n })\n\n // Filters\n .option('private', {\n type: 'boolean',\n group: 'Filters:',\n desc: 'Print only private workspaces',\n })\n\n // Affected filter\n .option('affected', {\n alias: 'a',\n type: 'string',\n coerce: (rev: string) => rev === '' ? 'master' : rev,\n group: 'Affected:',\n desc: 'Print only affected workspaces towards given git revision. If no revision is given, it will check towards master.\\n' +\n 'Replaces %name by workspace name.',\n })\n .option('affected-rev-sort', {\n type: 'string',\n group: 'Affected:',\n desc: 'Sort applied to git tag / git branch command',\n })\n .option('affected-rev-fallback', {\n type: 'string',\n default: 'master',\n group: 'Affected:',\n desc: 'Fallback revision, used if no revision matching the given format is found',\n }),\n async handler(args) {\n const app = container.get<ink.Instance>(INK_APP);\n const project = container.getNamed(Project, CURRENT);\n const manager = container.get(TaskManager);\n const spinner = container.get(SpinnerService);\n\n try {\n spinner.spin('Loading workspaces ...');\n\n // Setup pipeline\n const pipeline = new Pipeline();\n pipeline.add(new ScriptsFilter([args.script]));\n\n if (args.private !== undefined) {\n pipeline.add(new PrivateFilter(args.private));\n }\n\n if (args.affected !== undefined) {\n pipeline.add(new AffectedFilter(\n args.affected,\n args.affectedRevFallback,\n args.affectedRevSort\n ));\n }\n\n // Extract arguments\n const rest = args._.map(arg => arg.toString());\n\n if (rest[0] === 'each') {\n rest.splice(0, 1);\n }\n\n // Create script tasks\n const tasks = new TaskSet<WorkspaceContext>(manager);\n\n for await (const wks of pipeline.filter(project.workspaces())) {\n tasks.add(await wks.run(args.script, rest, {\n buildDeps: args.depsMode,\n }));\n }\n\n if (tasks.tasks.length === 0) {\n spinner.failed('No workspace found !');\n return yargs.exit(1, new Error('No workspace found !'));\n }\n\n spinner.stop();\n\n // Start and wait for result\n tasks.start();\n app.rerender(\n <Layout>\n <TasksSpinner manager={manager} />\n </Layout>\n );\n\n const result = await waitForEvent(tasks, 'finished');\n\n if (result.failed > 0) {\n return yargs.exit(1, new Error('A tasks failed !'));\n }\n } finally {\n spinner.stop();\n }\n }\n});\n"],"names":["defineCommand","command","describe","builder","yargs","applyMiddlewares","setupInk","loadProject","positional","type","demandOption","option","choice","default","desc","group","alias","coerce","rev","handler","args","app","container","get","INK_APP","project","getNamed","Project","CURRENT","manager","TaskManager","spinner","SpinnerService","spin","pipeline","Pipeline","add","ScriptsFilter","script","private","undefined","PrivateFilter","affected","AffectedFilter","affectedRevFallback","affectedRevSort","rest","_","map","arg","toString","splice","tasks","TaskSet","wks","filter","workspaces","run","buildDeps","depsMode","length","failed","exit","Error","stop","start","rerender","Layout","TasksSpinner","result","waitForEvent"],"mappings":"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","file":"each.js"}
@@ -0,0 +1,8 @@
1
+ /// <reference types="yargs" />
2
+ import { WorkspaceDepsMode } from '../project';
3
+ declare const _default: import("yargs").CommandModule<unknown, {
4
+ script: string;
5
+ } & {
6
+ "deps-mode": WorkspaceDepsMode;
7
+ }>;
8
+ export default _default;
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["commands/run.tsx"],"names":[],"mappings":";AAIA,OAAO,EAAa,iBAAiB,EAAE,MAAM,YAAY,CAAC;;;;;;AAM1D,wBA2CG","file":"run.d.ts","sourcesContent":["import { TaskManager } from '@jujulego/tasks';\nimport ink from 'ink';\n\nimport { loadProject, loadWorkspace, setupInk } from '../middlewares';\nimport { Workspace, WorkspaceDepsMode } from '../project';\nimport { container, CURRENT, INK_APP } from '../services';\nimport { Layout, TasksSpinner } from '../ui';\nimport { applyMiddlewares, defineCommand } from '../utils';\n\n// Command\nexport default defineCommand({\n command: 'run <script>',\n describe: 'Run script inside workspace',\n builder: (yargs) =>\n applyMiddlewares(yargs, [\n setupInk,\n loadProject,\n loadWorkspace\n ])\n .positional('script', { type: 'string', demandOption: true })\n .option('deps-mode', {\n choice: ['all', 'prod', 'none'],\n default: 'all' as WorkspaceDepsMode,\n desc: 'Dependency selection mode:\\n' +\n ' - all = dependencies AND devDependencies\\n' +\n ' - prod = dependencies\\n' +\n ' - none = nothing'\n }),\n async handler(args) {\n const app = container.get<ink.Instance>(INK_APP);\n const workspace = container.getNamed(Workspace, CURRENT);\n const manager = container.get(TaskManager);\n\n // Extract arguments\n const rest = args._.map(arg => arg.toString());\n\n if (rest[0] === 'run') {\n rest.splice(0, 1);\n }\n\n // Run script in workspace\n const task = await workspace.run(args.script, rest, {\n buildDeps: args.depsMode,\n });\n manager.add(task);\n\n // Render\n app.rerender(\n <Layout>\n <TasksSpinner manager={manager} />\n </Layout>\n );\n }\n});\n"]}
@@ -0,0 +1,59 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ Object.defineProperty(exports, // Command
6
+ "default", {
7
+ enumerable: true,
8
+ get: ()=>_default
9
+ });
10
+ const _jsxRuntime = require("react/jsx-runtime");
11
+ const _tasks = require("@jujulego/tasks");
12
+ const _middlewares = require("../middlewares");
13
+ const _project = require("../project");
14
+ const _services = require("../services");
15
+ const _ui = require("../ui");
16
+ const _utils = require("../utils");
17
+ const _default = (0, _utils.defineCommand)({
18
+ command: 'run <script>',
19
+ describe: 'Run script inside workspace',
20
+ builder: (yargs)=>(0, _utils.applyMiddlewares)(yargs, [
21
+ _middlewares.setupInk,
22
+ _middlewares.loadProject,
23
+ _middlewares.loadWorkspace
24
+ ]).positional('script', {
25
+ type: 'string',
26
+ demandOption: true
27
+ }).option('deps-mode', {
28
+ choice: [
29
+ 'all',
30
+ 'prod',
31
+ 'none'
32
+ ],
33
+ default: 'all',
34
+ desc: 'Dependency selection mode:\n' + ' - all = dependencies AND devDependencies\n' + ' - prod = dependencies\n' + ' - none = nothing'
35
+ }),
36
+ async handler (args) {
37
+ const app = _services.container.get(_services.INK_APP);
38
+ const workspace = _services.container.getNamed(_project.Workspace, _services.CURRENT);
39
+ const manager = _services.container.get(_tasks.TaskManager);
40
+ // Extract arguments
41
+ const rest = args._.map((arg)=>arg.toString());
42
+ if (rest[0] === 'run') {
43
+ rest.splice(0, 1);
44
+ }
45
+ // Run script in workspace
46
+ const task = await workspace.run(args.script, rest, {
47
+ buildDeps: args.depsMode
48
+ });
49
+ manager.add(task);
50
+ // Render
51
+ app.rerender(/*#__PURE__*/ (0, _jsxRuntime.jsx)(_ui.Layout, {
52
+ children: /*#__PURE__*/ (0, _jsxRuntime.jsx)(_ui.TasksSpinner, {
53
+ manager: manager
54
+ })
55
+ }));
56
+ }
57
+ });
58
+
59
+ //# sourceMappingURL=run.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["commands/run.js"],"sourcesContent":["import { TaskManager } from '@jujulego/tasks';\nimport ink from 'ink';\n\nimport { loadProject, loadWorkspace, setupInk } from '../middlewares';\nimport { Workspace, WorkspaceDepsMode } from '../project';\nimport { container, CURRENT, INK_APP } from '../services';\nimport { Layout, TasksSpinner } from '../ui';\nimport { applyMiddlewares, defineCommand } from '../utils';\n\n// Command\nexport default defineCommand({\n command: 'run <script>',\n describe: 'Run script inside workspace',\n builder: (yargs) =>\n applyMiddlewares(yargs, [\n setupInk,\n loadProject,\n loadWorkspace\n ])\n .positional('script', { type: 'string', demandOption: true })\n .option('deps-mode', {\n choice: ['all', 'prod', 'none'],\n default: 'all' as WorkspaceDepsMode,\n desc: 'Dependency selection mode:\\n' +\n ' - all = dependencies AND devDependencies\\n' +\n ' - prod = dependencies\\n' +\n ' - none = nothing'\n }),\n async handler(args) {\n const app = container.get<ink.Instance>(INK_APP);\n const workspace = container.getNamed(Workspace, CURRENT);\n const manager = container.get(TaskManager);\n\n // Extract arguments\n const rest = args._.map(arg => arg.toString());\n\n if (rest[0] === 'run') {\n rest.splice(0, 1);\n }\n\n // Run script in workspace\n const task = await workspace.run(args.script, rest, {\n buildDeps: args.depsMode,\n });\n manager.add(task);\n\n // Render\n app.rerender(\n <Layout>\n <TasksSpinner manager={manager} />\n </Layout>\n );\n }\n});\n"],"names":["defineCommand","command","describe","builder","yargs","applyMiddlewares","setupInk","loadProject","loadWorkspace","positional","type","demandOption","option","choice","default","desc","handler","args","app","container","get","INK_APP","workspace","getNamed","Workspace","CURRENT","manager","TaskManager","rest","_","map","arg","toString","splice","task","run","script","buildDeps","depsMode","add","rerender","Layout","TasksSpinner"],"mappings":"AAAA;;;;+BASA,UAAU;AACV;;aAAA;;;uBAV4B;6BAGyB;yBACR;0BACD;oBACP;uBACW;MAGhD,WAAeA,IAAAA,oBAAa,EAAC;IAC3BC,SAAS;IACTC,UAAU;IACVC,SAAS,CAACC,QACRC,IAAAA,uBAAgB,EAACD,OAAO;YACtBE,qBAAQ;YACRC,wBAAW;YACXC,0BAAa;SACd,EACEC,UAAU,CAAC,UAAU;YAAEC,MAAM;YAAUC,cAAc,IAAI;QAAC,GAC1DC,MAAM,CAAC,aAAa;YACnBC,QAAQ;gBAAC;gBAAO;gBAAQ;aAAO;YAC/BC,SAAS;YACTC,MAAM,iCACJ,gDACA,6BACA;QACJ;IACJ,MAAMC,SAAQC,IAAI,EAAE;QAClB,MAAMC,MAAMC,mBAAS,CAACC,GAAG,CAAeC,iBAAO;QAC/C,MAAMC,YAAYH,mBAAS,CAACI,QAAQ,CAACC,kBAAS,EAAEC,iBAAO;QACvD,MAAMC,UAAUP,mBAAS,CAACC,GAAG,CAACO,kBAAW;QAEzC,oBAAoB;QACpB,MAAMC,OAAOX,KAAKY,CAAC,CAACC,GAAG,CAACC,CAAAA,MAAOA,IAAIC,QAAQ;QAE3C,IAAIJ,IAAI,CAAC,EAAE,KAAK,OAAO;YACrBA,KAAKK,MAAM,CAAC,GAAG;QACjB,CAAC;QAED,0BAA0B;QAC1B,MAAMC,OAAO,MAAMZ,UAAUa,GAAG,CAAClB,KAAKmB,MAAM,EAAER,MAAM;YAClDS,WAAWpB,KAAKqB,QAAQ;QAC1B;QACAZ,QAAQa,GAAG,CAACL;QAEZ,SAAS;QACThB,IAAIsB,QAAQ,eACV,qBAACC,UAAM;sBACL,cAAA,qBAACC,gBAAY;gBAAChB,SAASA;;;IAG7B;AACF","file":"run.js"}
@@ -4,6 +4,7 @@ import { Project } from './project';
4
4
  export declare type WorkspaceDepsMode = 'all' | 'prod' | 'none';
5
5
  export interface WorkspaceContext extends TaskContext {
6
6
  workspace: Workspace;
7
+ script: string;
7
8
  }
8
9
  export interface WorkspaceRunOptions extends Omit<SpawnTaskOptions, 'cwd'> {
9
10
  buildDeps?: WorkspaceDepsMode;
@@ -23,6 +24,7 @@ export declare class Workspace {
23
24
  private _loadDependencies;
24
25
  dependencies(): AsyncGenerator<Workspace, void>;
25
26
  devDependencies(): AsyncGenerator<Workspace, void>;
27
+ private _streamLogs;
26
28
  run(script: string, args?: string[], opts?: WorkspaceRunOptions): Promise<SpawnTask<WorkspaceContext>>;
27
29
  build(opts?: WorkspaceRunOptions): Promise<SpawnTask | null>;
28
30
  get name(): string;
@@ -1 +1 @@
1
- {"version":3,"sources":["project/workspace.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAE3E,OAAO,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AAOjD,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAGpC,oBAAY,iBAAiB,GAAG,KAAK,GAAG,MAAM,GAAG,MAAM,CAAC;AAExD,MAAM,WAAW,gBAAiB,SAAQ,WAAW;IACnD,SAAS,EAAE,SAAS,CAAC;CACtB;AAED,MAAM,WAAW,mBAAoB,SAAQ,IAAI,CAAC,gBAAgB,EAAE,KAAK,CAAC;IACxE,SAAS,CAAC,EAAE,iBAAiB,CAAC;CAC/B;AAGD,qBAAa,SAAS;IAQlB,OAAO,CAAC,QAAQ,CAAC,IAAI;IACrB,QAAQ,CAAC,QAAQ,EAAE,OAAO;IAC1B,QAAQ,CAAC,OAAO,EAAE,OAAO;IAR3B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAiB;IACzC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAuC;IACtE,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAkD;gBAItD,IAAI,EAAE,MAAM,EACpB,QAAQ,EAAE,OAAO,EACjB,OAAO,EAAE,OAAO;IAO3B,OAAO,CAAC,UAAU;YAYJ,kBAAkB;YAuBlB,WAAW;IAqBnB,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;YAWtC,iBAAiB;IAczB,YAAY,IAAI,cAAc,CAAC,SAAS,EAAE,IAAI,CAAC;IAQ/C,eAAe,IAAI,cAAc,CAAC,SAAS,EAAE,IAAI,CAAC;IAQnD,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,GAAE,MAAM,EAAO,EAAE,IAAI,GAAE,mBAAwB,GAAG,OAAO,CAAC,SAAS,CAAC,gBAAgB,CAAC,CAAC;IAuB9G,KAAK,CAAC,IAAI,CAAC,EAAE,mBAAmB,GAAG,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC;IAYlE,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED,IAAI,OAAO,IAAI,MAAM,CAEpB;IAED,IAAI,SAAS,IAAI,MAAM,CAEtB;IAED,IAAI,GAAG,IAAI,MAAM,CAEhB;CACF","file":"workspace.d.ts","sourcesContent":["import { SpawnTask, SpawnTaskOptions, TaskContext } from '@jujulego/tasks';\nimport path from 'node:path';\nimport { Package } from 'normalize-package-data';\nimport { satisfies } from 'semver';\nimport winston from 'winston';\n\nimport { Git } from '../git';\nimport { container, Logger } from '../services';\nimport { combine } from '../utils';\nimport { Project } from './project';\n\n// Types\nexport type WorkspaceDepsMode = 'all' | 'prod' | 'none';\n\nexport interface WorkspaceContext extends TaskContext {\n workspace: Workspace;\n}\n\nexport interface WorkspaceRunOptions extends Omit<SpawnTaskOptions, 'cwd'> {\n buildDeps?: WorkspaceDepsMode;\n}\n\n// Class\nexport class Workspace {\n // Attributes\n private readonly _logger: winston.Logger;\n private readonly _affectedCache = new Map<string, Promise<boolean>>();\n private readonly _tasks = new Map<string, SpawnTask<WorkspaceContext>>();\n\n // Constructor\n constructor(\n private readonly _cwd: string,\n readonly manifest: Package,\n readonly project: Project\n ) {\n const logger = container.get(Logger);\n this._logger = logger.child({ label: this.manifest.name });\n }\n\n // Methods\n private _satisfies(from: Workspace, range: string): boolean {\n if (range.startsWith('file:')) {\n return path.resolve(from.cwd, range.substring(5)) === this.cwd;\n }\n\n if (range.startsWith('workspace:')) {\n range = range.substring(10);\n }\n\n return !this.version || satisfies(this.version, range);\n }\n\n private async _buildDependencies(task: SpawnTask, deps: WorkspaceDepsMode = 'all') {\n // Generators\n const generators: AsyncGenerator<Workspace, void>[] = [];\n\n switch (deps) {\n case 'all':\n generators.unshift(this.devDependencies());\n\n // eslint-disable-next no-fallthrough\n case 'prod':\n generators.unshift(this.dependencies());\n }\n\n // Build deps\n for await (const dep of combine(...generators)) {\n const build = await dep.build();\n\n if (build) {\n task.dependsOn(build);\n }\n }\n }\n\n private async _isAffected(reference: string): Promise<boolean> {\n const isAffected = await Git.isAffected(reference, ['--', this.cwd], {\n cwd: this.project.root,\n logger: this._logger,\n });\n\n if (isAffected) {\n return true;\n }\n\n // Test dependencies\n const proms: Promise<boolean>[] = [];\n\n for await (const dep of combine(this.dependencies(), this.devDependencies())) {\n proms.push(dep.isAffected(reference));\n }\n\n const results = await Promise.all(proms);\n return results.some(r => r);\n }\n\n async isAffected(reference: string): Promise<boolean> {\n let isAffected = this._affectedCache.get(reference);\n\n if (!isAffected) {\n isAffected = this._isAffected(reference);\n this._affectedCache.set(reference, isAffected);\n }\n\n return await isAffected;\n }\n\n private async* _loadDependencies(dependencies: Record<string, string>, kind: string): AsyncGenerator<Workspace, void> {\n for (const [dep, range] of Object.entries(dependencies)) {\n const ws = await this.project.workspace(dep);\n\n if (ws) {\n if (ws._satisfies(this, range)) {\n yield ws;\n } else {\n this._logger.verbose(`Ignoring ${kind} ${ws.reference} as it does not match requirement ${range}`);\n }\n }\n }\n }\n\n async* dependencies(): AsyncGenerator<Workspace, void> {\n if (!this.manifest.dependencies) return;\n\n for await (const ws of this._loadDependencies(this.manifest.dependencies, 'dependency')) {\n yield ws;\n }\n }\n\n async* devDependencies(): AsyncGenerator<Workspace, void> {\n if (!this.manifest.devDependencies) return;\n\n for await (const ws of this._loadDependencies(this.manifest.devDependencies, 'devDependency')) {\n yield ws;\n }\n }\n\n async run(script: string, args: string[] = [], opts: WorkspaceRunOptions = {}): Promise<SpawnTask<WorkspaceContext>> {\n let task = this._tasks.get(script);\n\n if (!task) {\n const pm = await this.project.packageManager();\n\n task = new SpawnTask(pm, ['run', script, ...args], { workspace: this }, {\n ...opts,\n cwd: this.cwd,\n logger: this._logger,\n env: {\n FORCE_COLOR: '1',\n ...opts.env\n }\n });\n await this._buildDependencies(task, opts.buildDeps);\n\n this._tasks.set(script, task);\n }\n\n return task;\n }\n\n async build(opts?: WorkspaceRunOptions): Promise<SpawnTask | null> {\n const { scripts = {} } = this.manifest;\n\n if (!scripts.build) {\n this._logger.warn('Will not be built (no build script)');\n return null;\n }\n\n return await this.run('build', [], opts);\n }\n\n // Properties\n get name(): string {\n return this.manifest.name;\n }\n\n get version(): string {\n return this.manifest.version;\n }\n\n get reference(): string {\n return this.version ? `${this.name}@${this.version}` : this.name;\n }\n\n get cwd(): string {\n return path.resolve(this.project.root, this._cwd);\n }\n}\n"]}
1
+ {"version":3,"sources":["project/workspace.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,gBAAgB,EAAmB,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAE5F,OAAO,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AAOjD,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAGpC,oBAAY,iBAAiB,GAAG,KAAK,GAAG,MAAM,GAAG,MAAM,CAAC;AAExD,MAAM,WAAW,gBAAiB,SAAQ,WAAW;IACnD,SAAS,EAAE,SAAS,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,mBAAoB,SAAQ,IAAI,CAAC,gBAAgB,EAAE,KAAK,CAAC;IACxE,SAAS,CAAC,EAAE,iBAAiB,CAAC;CAC/B;AAGD,qBAAa,SAAS;IAQlB,OAAO,CAAC,QAAQ,CAAC,IAAI;IACrB,QAAQ,CAAC,QAAQ,EAAE,OAAO;IAC1B,QAAQ,CAAC,OAAO,EAAE,OAAO;IAR3B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAiB;IACzC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAuC;IACtE,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAkD;gBAItD,IAAI,EAAE,MAAM,EACpB,QAAQ,EAAE,OAAO,EACjB,OAAO,EAAE,OAAO;IAO3B,OAAO,CAAC,UAAU;YAYJ,kBAAkB;YAuBlB,WAAW;IAqBnB,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;YAWtC,iBAAiB;IAczB,YAAY,IAAI,cAAc,CAAC,SAAS,EAAE,IAAI,CAAC;IAQ/C,eAAe,IAAI,cAAc,CAAC,SAAS,EAAE,IAAI,CAAC;YAQ3C,WAAW;IAYnB,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,GAAE,MAAM,EAAO,EAAE,IAAI,GAAE,mBAAwB,GAAG,OAAO,CAAC,SAAS,CAAC,gBAAgB,CAAC,CAAC;IA2B9G,KAAK,CAAC,IAAI,CAAC,EAAE,mBAAmB,GAAG,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC;IAYlE,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED,IAAI,OAAO,IAAI,MAAM,CAEpB;IAED,IAAI,SAAS,IAAI,MAAM,CAEtB;IAED,IAAI,GAAG,IAAI,MAAM,CAEhB;CACF","file":"workspace.d.ts","sourcesContent":["import { SpawnTask, SpawnTaskOptions, SpawnTaskStream, TaskContext } from '@jujulego/tasks';\nimport path from 'node:path';\nimport { Package } from 'normalize-package-data';\nimport { satisfies } from 'semver';\nimport winston from 'winston';\n\nimport { Git } from '../git';\nimport { container, Logger } from '../services';\nimport { combine, streamLines } from '../utils';\nimport { Project } from './project';\n\n// Types\nexport type WorkspaceDepsMode = 'all' | 'prod' | 'none';\n\nexport interface WorkspaceContext extends TaskContext {\n workspace: Workspace;\n script: string;\n}\n\nexport interface WorkspaceRunOptions extends Omit<SpawnTaskOptions, 'cwd'> {\n buildDeps?: WorkspaceDepsMode;\n}\n\n// Class\nexport class Workspace {\n // Attributes\n private readonly _logger: winston.Logger;\n private readonly _affectedCache = new Map<string, Promise<boolean>>();\n private readonly _tasks = new Map<string, SpawnTask<WorkspaceContext>>();\n\n // Constructor\n constructor(\n private readonly _cwd: string,\n readonly manifest: Package,\n readonly project: Project\n ) {\n const logger = container.get(Logger);\n this._logger = logger.child({ label: this.manifest.name });\n }\n\n // Methods\n private _satisfies(from: Workspace, range: string): boolean {\n if (range.startsWith('file:')) {\n return path.resolve(from.cwd, range.substring(5)) === this.cwd;\n }\n\n if (range.startsWith('workspace:')) {\n range = range.substring(10);\n }\n\n return !this.version || satisfies(this.version, range);\n }\n\n private async _buildDependencies(task: SpawnTask, deps: WorkspaceDepsMode = 'all') {\n // Generators\n const generators: AsyncGenerator<Workspace, void>[] = [];\n\n switch (deps) {\n case 'all':\n generators.unshift(this.devDependencies());\n\n // eslint-disable-next no-fallthrough\n case 'prod':\n generators.unshift(this.dependencies());\n }\n\n // Build deps\n for await (const dep of combine(...generators)) {\n const build = await dep.build();\n\n if (build) {\n task.dependsOn(build);\n }\n }\n }\n\n private async _isAffected(reference: string): Promise<boolean> {\n const isAffected = await Git.isAffected(reference, ['--', this.cwd], {\n cwd: this.project.root,\n logger: this._logger,\n });\n\n if (isAffected) {\n return true;\n }\n\n // Test dependencies\n const proms: Promise<boolean>[] = [];\n\n for await (const dep of combine(this.dependencies(), this.devDependencies())) {\n proms.push(dep.isAffected(reference));\n }\n\n const results = await Promise.all(proms);\n return results.some(r => r);\n }\n\n async isAffected(reference: string): Promise<boolean> {\n let isAffected = this._affectedCache.get(reference);\n\n if (!isAffected) {\n isAffected = this._isAffected(reference);\n this._affectedCache.set(reference, isAffected);\n }\n\n return await isAffected;\n }\n\n private async* _loadDependencies(dependencies: Record<string, string>, kind: string): AsyncGenerator<Workspace, void> {\n for (const [dep, range] of Object.entries(dependencies)) {\n const ws = await this.project.workspace(dep);\n\n if (ws) {\n if (ws._satisfies(this, range)) {\n yield ws;\n } else {\n this._logger.verbose(`Ignoring ${kind} ${ws.reference} as it does not match requirement ${range}`);\n }\n }\n }\n }\n\n async* dependencies(): AsyncGenerator<Workspace, void> {\n if (!this.manifest.dependencies) return;\n\n for await (const ws of this._loadDependencies(this.manifest.dependencies, 'dependency')) {\n yield ws;\n }\n }\n\n async* devDependencies(): AsyncGenerator<Workspace, void> {\n if (!this.manifest.devDependencies) return;\n\n for await (const ws of this._loadDependencies(this.manifest.devDependencies, 'devDependency')) {\n yield ws;\n }\n }\n\n private async _streamLogs(task: SpawnTask<WorkspaceContext>, stream: SpawnTaskStream, level: string) {\n try {\n for await (const line of streamLines(task, stream)) {\n this._logger.log(level, line);\n }\n } catch (err) {\n if (err) {\n this._logger.warn(`Error while streaming task ${stream}`, err);\n }\n }\n }\n\n async run(script: string, args: string[] = [], opts: WorkspaceRunOptions = {}): Promise<SpawnTask<WorkspaceContext>> {\n let task = this._tasks.get(script);\n\n if (!task) {\n const pm = await this.project.packageManager();\n\n task = new SpawnTask(pm, ['run', script, ...args], { workspace: this, script }, {\n ...opts,\n cwd: this.cwd,\n logger: this._logger,\n env: {\n FORCE_COLOR: '1',\n ...opts.env\n }\n });\n\n this._streamLogs(task, 'stdout', 'info');\n this._streamLogs(task, 'stderr', 'info');\n\n await this._buildDependencies(task, opts.buildDeps);\n\n this._tasks.set(script, task);\n }\n\n return task;\n }\n\n async build(opts?: WorkspaceRunOptions): Promise<SpawnTask | null> {\n const { scripts = {} } = this.manifest;\n\n if (!scripts.build) {\n this._logger.warn('Will not be built (no build script)');\n return null;\n }\n\n return await this.run('build', [], opts);\n }\n\n // Properties\n get name(): string {\n return this.manifest.name;\n }\n\n get version(): string {\n return this.manifest.version;\n }\n\n get reference(): string {\n return this.version ? `${this.name}@${this.version}` : this.name;\n }\n\n get cwd(): string {\n return path.resolve(this.project.root, this._cwd);\n }\n}\n"]}
@@ -109,6 +109,17 @@ class Workspace {
109
109
  yield ws;
110
110
  }
111
111
  }
112
+ async _streamLogs(task, stream, level) {
113
+ try {
114
+ for await (const line of (0, _utils.streamLines)(task, stream)){
115
+ this._logger.log(level, line);
116
+ }
117
+ } catch (err) {
118
+ if (err) {
119
+ this._logger.warn(`Error while streaming task ${stream}`, err);
120
+ }
121
+ }
122
+ }
112
123
  async run(script, args = [], opts = {}) {
113
124
  let task = this._tasks.get(script);
114
125
  if (!task) {
@@ -118,7 +129,8 @@ class Workspace {
118
129
  script,
119
130
  ...args
120
131
  ], {
121
- workspace: this
132
+ workspace: this,
133
+ script
122
134
  }, {
123
135
  ...opts,
124
136
  cwd: this.cwd,
@@ -128,6 +140,8 @@ class Workspace {
128
140
  ...opts.env
129
141
  }
130
142
  });
143
+ this._streamLogs(task, 'stdout', 'info');
144
+ this._streamLogs(task, 'stderr', 'info');
131
145
  await this._buildDependencies(task, opts.buildDeps);
132
146
  this._tasks.set(script, task);
133
147
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["project/workspace.js"],"sourcesContent":["import { SpawnTask, SpawnTaskOptions, TaskContext } from '@jujulego/tasks';\nimport path from 'node:path';\nimport { Package } from 'normalize-package-data';\nimport { satisfies } from 'semver';\nimport winston from 'winston';\n\nimport { Git } from '../git';\nimport { container, Logger } from '../services';\nimport { combine } from '../utils';\nimport { Project } from './project';\n\n// Types\nexport type WorkspaceDepsMode = 'all' | 'prod' | 'none';\n\nexport interface WorkspaceContext extends TaskContext {\n workspace: Workspace;\n}\n\nexport interface WorkspaceRunOptions extends Omit<SpawnTaskOptions, 'cwd'> {\n buildDeps?: WorkspaceDepsMode;\n}\n\n// Class\nexport class Workspace {\n // Attributes\n private readonly _logger: winston.Logger;\n private readonly _affectedCache = new Map<string, Promise<boolean>>();\n private readonly _tasks = new Map<string, SpawnTask<WorkspaceContext>>();\n\n // Constructor\n constructor(\n private readonly _cwd: string,\n readonly manifest: Package,\n readonly project: Project\n ) {\n const logger = container.get(Logger);\n this._logger = logger.child({ label: this.manifest.name });\n }\n\n // Methods\n private _satisfies(from: Workspace, range: string): boolean {\n if (range.startsWith('file:')) {\n return path.resolve(from.cwd, range.substring(5)) === this.cwd;\n }\n\n if (range.startsWith('workspace:')) {\n range = range.substring(10);\n }\n\n return !this.version || satisfies(this.version, range);\n }\n\n private async _buildDependencies(task: SpawnTask, deps: WorkspaceDepsMode = 'all') {\n // Generators\n const generators: AsyncGenerator<Workspace, void>[] = [];\n\n switch (deps) {\n case 'all':\n generators.unshift(this.devDependencies());\n\n // eslint-disable-next no-fallthrough\n case 'prod':\n generators.unshift(this.dependencies());\n }\n\n // Build deps\n for await (const dep of combine(...generators)) {\n const build = await dep.build();\n\n if (build) {\n task.dependsOn(build);\n }\n }\n }\n\n private async _isAffected(reference: string): Promise<boolean> {\n const isAffected = await Git.isAffected(reference, ['--', this.cwd], {\n cwd: this.project.root,\n logger: this._logger,\n });\n\n if (isAffected) {\n return true;\n }\n\n // Test dependencies\n const proms: Promise<boolean>[] = [];\n\n for await (const dep of combine(this.dependencies(), this.devDependencies())) {\n proms.push(dep.isAffected(reference));\n }\n\n const results = await Promise.all(proms);\n return results.some(r => r);\n }\n\n async isAffected(reference: string): Promise<boolean> {\n let isAffected = this._affectedCache.get(reference);\n\n if (!isAffected) {\n isAffected = this._isAffected(reference);\n this._affectedCache.set(reference, isAffected);\n }\n\n return await isAffected;\n }\n\n private async* _loadDependencies(dependencies: Record<string, string>, kind: string): AsyncGenerator<Workspace, void> {\n for (const [dep, range] of Object.entries(dependencies)) {\n const ws = await this.project.workspace(dep);\n\n if (ws) {\n if (ws._satisfies(this, range)) {\n yield ws;\n } else {\n this._logger.verbose(`Ignoring ${kind} ${ws.reference} as it does not match requirement ${range}`);\n }\n }\n }\n }\n\n async* dependencies(): AsyncGenerator<Workspace, void> {\n if (!this.manifest.dependencies) return;\n\n for await (const ws of this._loadDependencies(this.manifest.dependencies, 'dependency')) {\n yield ws;\n }\n }\n\n async* devDependencies(): AsyncGenerator<Workspace, void> {\n if (!this.manifest.devDependencies) return;\n\n for await (const ws of this._loadDependencies(this.manifest.devDependencies, 'devDependency')) {\n yield ws;\n }\n }\n\n async run(script: string, args: string[] = [], opts: WorkspaceRunOptions = {}): Promise<SpawnTask<WorkspaceContext>> {\n let task = this._tasks.get(script);\n\n if (!task) {\n const pm = await this.project.packageManager();\n\n task = new SpawnTask(pm, ['run', script, ...args], { workspace: this }, {\n ...opts,\n cwd: this.cwd,\n logger: this._logger,\n env: {\n FORCE_COLOR: '1',\n ...opts.env\n }\n });\n await this._buildDependencies(task, opts.buildDeps);\n\n this._tasks.set(script, task);\n }\n\n return task;\n }\n\n async build(opts?: WorkspaceRunOptions): Promise<SpawnTask | null> {\n const { scripts = {} } = this.manifest;\n\n if (!scripts.build) {\n this._logger.warn('Will not be built (no build script)');\n return null;\n }\n\n return await this.run('build', [], opts);\n }\n\n // Properties\n get name(): string {\n return this.manifest.name;\n }\n\n get version(): string {\n return this.manifest.version;\n }\n\n get reference(): string {\n return this.version ? `${this.name}@${this.version}` : this.name;\n }\n\n get cwd(): string {\n return path.resolve(this.project.root, this._cwd);\n }\n}\n"],"names":["Workspace","constructor","_cwd","manifest","project","_affectedCache","Map","_tasks","logger","container","get","Logger","_logger","child","label","name","_satisfies","from","range","startsWith","path","resolve","cwd","substring","version","satisfies","_buildDependencies","task","deps","generators","unshift","devDependencies","dependencies","dep","combine","build","dependsOn","_isAffected","reference","isAffected","Git","root","proms","push","results","Promise","all","some","r","set","_loadDependencies","kind","Object","entries","ws","workspace","verbose","run","script","args","opts","pm","packageManager","SpawnTask","env","FORCE_COLOR","buildDeps","scripts","warn"],"mappings":"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","file":"workspace.js"}
1
+ {"version":3,"sources":["project/workspace.js"],"sourcesContent":["import { SpawnTask, SpawnTaskOptions, SpawnTaskStream, TaskContext } from '@jujulego/tasks';\nimport path from 'node:path';\nimport { Package } from 'normalize-package-data';\nimport { satisfies } from 'semver';\nimport winston from 'winston';\n\nimport { Git } from '../git';\nimport { container, Logger } from '../services';\nimport { combine, streamLines } from '../utils';\nimport { Project } from './project';\n\n// Types\nexport type WorkspaceDepsMode = 'all' | 'prod' | 'none';\n\nexport interface WorkspaceContext extends TaskContext {\n workspace: Workspace;\n script: string;\n}\n\nexport interface WorkspaceRunOptions extends Omit<SpawnTaskOptions, 'cwd'> {\n buildDeps?: WorkspaceDepsMode;\n}\n\n// Class\nexport class Workspace {\n // Attributes\n private readonly _logger: winston.Logger;\n private readonly _affectedCache = new Map<string, Promise<boolean>>();\n private readonly _tasks = new Map<string, SpawnTask<WorkspaceContext>>();\n\n // Constructor\n constructor(\n private readonly _cwd: string,\n readonly manifest: Package,\n readonly project: Project\n ) {\n const logger = container.get(Logger);\n this._logger = logger.child({ label: this.manifest.name });\n }\n\n // Methods\n private _satisfies(from: Workspace, range: string): boolean {\n if (range.startsWith('file:')) {\n return path.resolve(from.cwd, range.substring(5)) === this.cwd;\n }\n\n if (range.startsWith('workspace:')) {\n range = range.substring(10);\n }\n\n return !this.version || satisfies(this.version, range);\n }\n\n private async _buildDependencies(task: SpawnTask, deps: WorkspaceDepsMode = 'all') {\n // Generators\n const generators: AsyncGenerator<Workspace, void>[] = [];\n\n switch (deps) {\n case 'all':\n generators.unshift(this.devDependencies());\n\n // eslint-disable-next no-fallthrough\n case 'prod':\n generators.unshift(this.dependencies());\n }\n\n // Build deps\n for await (const dep of combine(...generators)) {\n const build = await dep.build();\n\n if (build) {\n task.dependsOn(build);\n }\n }\n }\n\n private async _isAffected(reference: string): Promise<boolean> {\n const isAffected = await Git.isAffected(reference, ['--', this.cwd], {\n cwd: this.project.root,\n logger: this._logger,\n });\n\n if (isAffected) {\n return true;\n }\n\n // Test dependencies\n const proms: Promise<boolean>[] = [];\n\n for await (const dep of combine(this.dependencies(), this.devDependencies())) {\n proms.push(dep.isAffected(reference));\n }\n\n const results = await Promise.all(proms);\n return results.some(r => r);\n }\n\n async isAffected(reference: string): Promise<boolean> {\n let isAffected = this._affectedCache.get(reference);\n\n if (!isAffected) {\n isAffected = this._isAffected(reference);\n this._affectedCache.set(reference, isAffected);\n }\n\n return await isAffected;\n }\n\n private async* _loadDependencies(dependencies: Record<string, string>, kind: string): AsyncGenerator<Workspace, void> {\n for (const [dep, range] of Object.entries(dependencies)) {\n const ws = await this.project.workspace(dep);\n\n if (ws) {\n if (ws._satisfies(this, range)) {\n yield ws;\n } else {\n this._logger.verbose(`Ignoring ${kind} ${ws.reference} as it does not match requirement ${range}`);\n }\n }\n }\n }\n\n async* dependencies(): AsyncGenerator<Workspace, void> {\n if (!this.manifest.dependencies) return;\n\n for await (const ws of this._loadDependencies(this.manifest.dependencies, 'dependency')) {\n yield ws;\n }\n }\n\n async* devDependencies(): AsyncGenerator<Workspace, void> {\n if (!this.manifest.devDependencies) return;\n\n for await (const ws of this._loadDependencies(this.manifest.devDependencies, 'devDependency')) {\n yield ws;\n }\n }\n\n private async _streamLogs(task: SpawnTask<WorkspaceContext>, stream: SpawnTaskStream, level: string) {\n try {\n for await (const line of streamLines(task, stream)) {\n this._logger.log(level, line);\n }\n } catch (err) {\n if (err) {\n this._logger.warn(`Error while streaming task ${stream}`, err);\n }\n }\n }\n\n async run(script: string, args: string[] = [], opts: WorkspaceRunOptions = {}): Promise<SpawnTask<WorkspaceContext>> {\n let task = this._tasks.get(script);\n\n if (!task) {\n const pm = await this.project.packageManager();\n\n task = new SpawnTask(pm, ['run', script, ...args], { workspace: this, script }, {\n ...opts,\n cwd: this.cwd,\n logger: this._logger,\n env: {\n FORCE_COLOR: '1',\n ...opts.env\n }\n });\n\n this._streamLogs(task, 'stdout', 'info');\n this._streamLogs(task, 'stderr', 'info');\n\n await this._buildDependencies(task, opts.buildDeps);\n\n this._tasks.set(script, task);\n }\n\n return task;\n }\n\n async build(opts?: WorkspaceRunOptions): Promise<SpawnTask | null> {\n const { scripts = {} } = this.manifest;\n\n if (!scripts.build) {\n this._logger.warn('Will not be built (no build script)');\n return null;\n }\n\n return await this.run('build', [], opts);\n }\n\n // Properties\n get name(): string {\n return this.manifest.name;\n }\n\n get version(): string {\n return this.manifest.version;\n }\n\n get reference(): string {\n return this.version ? `${this.name}@${this.version}` : this.name;\n }\n\n get cwd(): string {\n return path.resolve(this.project.root, this._cwd);\n }\n}\n"],"names":["Workspace","constructor","_cwd","manifest","project","_affectedCache","Map","_tasks","logger","container","get","Logger","_logger","child","label","name","_satisfies","from","range","startsWith","path","resolve","cwd","substring","version","satisfies","_buildDependencies","task","deps","generators","unshift","devDependencies","dependencies","dep","combine","build","dependsOn","_isAffected","reference","isAffected","Git","root","proms","push","results","Promise","all","some","r","set","_loadDependencies","kind","Object","entries","ws","workspace","verbose","_streamLogs","stream","level","line","streamLines","log","err","warn","run","script","args","opts","pm","packageManager","SpawnTask","env","FORCE_COLOR","buildDeps","scripts"],"mappings":"AAAA;;;;+BAwBaA;;aAAAA;;uBAxB6D;+DACzD;wBAES;qBAGN;0BACc;uBACG;;;;;;AAgB9B,MAAMA;IAMX,cAAc;IACdC,YACmBC,MACRC,UACAC,QACT;oBAHiBF;wBACRC;uBACAC;aAPMC,iBAAiB,IAAIC;aACrBC,SAAS,IAAID;QAQ5B,MAAME,SAASC,mBAAS,CAACC,GAAG,CAACC,gBAAM;QACnC,IAAI,CAACC,OAAO,GAAGJ,OAAOK,KAAK,CAAC;YAAEC,OAAO,IAAI,CAACX,QAAQ,CAACY,IAAI;QAAC;IAC1D;IAEA,UAAU;IACFC,WAAWC,IAAe,EAAEC,KAAa,EAAW;QAC1D,IAAIA,MAAMC,UAAU,CAAC,UAAU;YAC7B,OAAOC,iBAAI,CAACC,OAAO,CAACJ,KAAKK,GAAG,EAAEJ,MAAMK,SAAS,CAAC,QAAQ,IAAI,CAACD,GAAG;QAChE,CAAC;QAED,IAAIJ,MAAMC,UAAU,CAAC,eAAe;YAClCD,QAAQA,MAAMK,SAAS,CAAC;QAC1B,CAAC;QAED,OAAO,CAAC,IAAI,CAACC,OAAO,IAAIC,IAAAA,iBAAS,EAAC,IAAI,CAACD,OAAO,EAAEN;IAClD;IAEA,MAAcQ,mBAAmBC,IAAe,EAAEC,OAA0B,KAAK,EAAE;QACjF,aAAa;QACb,MAAMC,aAAgD,EAAE;QAExD,OAAQD;YACN,KAAK;gBACHC,WAAWC,OAAO,CAAC,IAAI,CAACC,eAAe;YAEzC,qCAAqC;YACrC,KAAK;gBACHF,WAAWC,OAAO,CAAC,IAAI,CAACE,YAAY;QACxC;QAEA,aAAa;QACb,WAAW,MAAMC,OAAOC,IAAAA,cAAO,KAAIL,YAAa;YAC9C,MAAMM,QAAQ,MAAMF,IAAIE,KAAK;YAE7B,IAAIA,OAAO;gBACTR,KAAKS,SAAS,CAACD;YACjB,CAAC;QACH;IACF;IAEA,MAAcE,YAAYC,SAAiB,EAAoB;QAC7D,MAAMC,aAAa,MAAMC,QAAG,CAACD,UAAU,CAACD,WAAW;YAAC;YAAM,IAAI,CAAChB,GAAG;SAAC,EAAE;YACnEA,KAAK,IAAI,CAAClB,OAAO,CAACqC,IAAI;YACtBjC,QAAQ,IAAI,CAACI,OAAO;QACtB;QAEA,IAAI2B,YAAY;YACd,OAAO,IAAI;QACb,CAAC;QAED,oBAAoB;QACpB,MAAMG,QAA4B,EAAE;QAEpC,WAAW,MAAMT,OAAOC,IAAAA,cAAO,EAAC,IAAI,CAACF,YAAY,IAAI,IAAI,CAACD,eAAe,IAAK;YAC5EW,MAAMC,IAAI,CAACV,IAAIM,UAAU,CAACD;QAC5B;QAEA,MAAMM,UAAU,MAAMC,QAAQC,GAAG,CAACJ;QAClC,OAAOE,QAAQG,IAAI,CAACC,CAAAA,IAAKA;IAC3B;IAEA,MAAMT,WAAWD,SAAiB,EAAoB;QACpD,IAAIC,aAAa,IAAI,CAAClC,cAAc,CAACK,GAAG,CAAC4B;QAEzC,IAAI,CAACC,YAAY;YACfA,aAAa,IAAI,CAACF,WAAW,CAACC;YAC9B,IAAI,CAACjC,cAAc,CAAC4C,GAAG,CAACX,WAAWC;QACrC,CAAC;QAED,OAAO,MAAMA;IACf;IAEA,OAAeW,kBAAkBlB,YAAoC,EAAEmB,IAAY,EAAmC;QACpH,KAAK,MAAM,CAAClB,KAAKf,MAAM,IAAIkC,OAAOC,OAAO,CAACrB,cAAe;YACvD,MAAMsB,KAAK,MAAM,IAAI,CAAClD,OAAO,CAACmD,SAAS,CAACtB;YAExC,IAAIqB,IAAI;gBACN,IAAIA,GAAGtC,UAAU,CAAC,IAAI,EAAEE,QAAQ;oBAC9B,MAAMoC;gBACR,OAAO;oBACL,IAAI,CAAC1C,OAAO,CAAC4C,OAAO,CAAC,CAAC,SAAS,EAAEL,KAAK,CAAC,EAAEG,GAAGhB,SAAS,CAAC,kCAAkC,EAAEpB,MAAM,CAAC;gBACnG,CAAC;YACH,CAAC;QACH;IACF;IAEA,OAAOc,eAAgD;QACrD,IAAI,CAAC,IAAI,CAAC7B,QAAQ,CAAC6B,YAAY,EAAE;QAEjC,WAAW,MAAMsB,MAAM,IAAI,CAACJ,iBAAiB,CAAC,IAAI,CAAC/C,QAAQ,CAAC6B,YAAY,EAAE,cAAe;YACvF,MAAMsB;QACR;IACF;IAEA,OAAOvB,kBAAmD;QACxD,IAAI,CAAC,IAAI,CAAC5B,QAAQ,CAAC4B,eAAe,EAAE;QAEpC,WAAW,MAAMuB,MAAM,IAAI,CAACJ,iBAAiB,CAAC,IAAI,CAAC/C,QAAQ,CAAC4B,eAAe,EAAE,iBAAkB;YAC7F,MAAMuB;QACR;IACF;IAEA,MAAcG,YAAY9B,IAAiC,EAAE+B,MAAuB,EAAEC,KAAa,EAAE;QACnG,IAAI;YACF,WAAW,MAAMC,QAAQC,IAAAA,kBAAW,EAAClC,MAAM+B,QAAS;gBAClD,IAAI,CAAC9C,OAAO,CAACkD,GAAG,CAACH,OAAOC;YAC1B;QACF,EAAE,OAAOG,KAAK;YACZ,IAAIA,KAAK;gBACP,IAAI,CAACnD,OAAO,CAACoD,IAAI,CAAC,CAAC,2BAA2B,EAAEN,OAAO,CAAC,EAAEK;YAC5D,CAAC;QACH;IACF;IAEA,MAAME,IAAIC,MAAc,EAAEC,OAAiB,EAAE,EAAEC,OAA4B,CAAC,CAAC,EAAwC;QACnH,IAAIzC,OAAO,IAAI,CAACpB,MAAM,CAACG,GAAG,CAACwD;QAE3B,IAAI,CAACvC,MAAM;YACT,MAAM0C,KAAK,MAAM,IAAI,CAACjE,OAAO,CAACkE,cAAc;YAE5C3C,OAAO,IAAI4C,gBAAS,CAACF,IAAI;gBAAC;gBAAOH;mBAAWC;aAAK,EAAE;gBAAEZ,WAAW,IAAI;gBAAEW;YAAO,GAAG;gBAC9E,GAAGE,IAAI;gBACP9C,KAAK,IAAI,CAACA,GAAG;gBACbd,QAAQ,IAAI,CAACI,OAAO;gBACpB4D,KAAK;oBACHC,aAAa;oBACb,GAAGL,KAAKI,GAAG;gBACb;YACF;YAEA,IAAI,CAACf,WAAW,CAAC9B,MAAM,UAAU;YACjC,IAAI,CAAC8B,WAAW,CAAC9B,MAAM,UAAU;YAEjC,MAAM,IAAI,CAACD,kBAAkB,CAACC,MAAMyC,KAAKM,SAAS;YAElD,IAAI,CAACnE,MAAM,CAAC0C,GAAG,CAACiB,QAAQvC;QAC1B,CAAC;QAED,OAAOA;IACT;IAEA,MAAMQ,MAAMiC,IAA0B,EAA6B;QACjE,MAAM,EAAEO,SAAU,CAAC,EAAC,EAAE,GAAG,IAAI,CAACxE,QAAQ;QAEtC,IAAI,CAACwE,QAAQxC,KAAK,EAAE;YAClB,IAAI,CAACvB,OAAO,CAACoD,IAAI,CAAC;YAClB,OAAO,IAAI;QACb,CAAC;QAED,OAAO,MAAM,IAAI,CAACC,GAAG,CAAC,SAAS,EAAE,EAAEG;IACrC;IAEA,aAAa;IACb,IAAIrD,OAAe;QACjB,OAAO,IAAI,CAACZ,QAAQ,CAACY,IAAI;IAC3B;IAEA,IAAIS,UAAkB;QACpB,OAAO,IAAI,CAACrB,QAAQ,CAACqB,OAAO;IAC9B;IAEA,IAAIc,YAAoB;QACtB,OAAO,IAAI,CAACd,OAAO,GAAG,CAAC,EAAE,IAAI,CAACT,IAAI,CAAC,CAAC,EAAE,IAAI,CAACS,OAAO,CAAC,CAAC,GAAG,IAAI,CAACT,IAAI;IAClE;IAEA,IAAIO,MAAc;QAChB,OAAOF,iBAAI,CAACC,OAAO,CAAC,IAAI,CAACjB,OAAO,CAACqC,IAAI,EAAE,IAAI,CAACvC,IAAI;IAClD;AACF","file":"workspace.js"}
@@ -1 +1 @@
1
- {"version":3,"sources":["services/logger.service.ts"],"names":[],"mappings":"AAEA,OAAO,OAAO,MAAM,SAAS,CAAC;AAW9B,eAAO,MAAM,aAAa,wBAwBzB,CAAC;AAGF,qBACa,MAAM;CAAG;AAGtB,MAAM,WAAW,MAAO,SAAQ,OAAO,CAAC,MAAM;CAAG","file":"logger.service.d.ts","sourcesContent":["import chalk from 'chalk';\nimport { injectable } from 'inversify';\nimport winston from 'winston';\n\nimport { type GlobalConfig, GLOBAL_CONFIG, container } from './inversify.config';\n\n// Constants\nconst VERBOSITY_LEVEL: Record<number, string> = {\n 1: 'verbose',\n 2: 'debug',\n};\n\n// Utils\nexport const consoleFormat = winston.format.combine(\n winston.format.errors(),\n winston.format.colorize({\n message: true,\n colors: { debug: 'grey', verbose: 'blue', info: 'white', error: 'red' }\n }),\n winston.format.printf(({ label, message, ms }) => {\n const lines = message.split('\\n');\n\n // Format\n let spaces = '';\n let formatted = `${lines[0]} ${chalk.magenta(ms)}`;\n\n if (label) {\n spaces = ' '.repeat(label.length + 3);\n formatted = `${chalk.grey(`[${label}]`)} ${lines[0]} ${chalk.magenta(ms)}`;\n }\n\n for (let i = 1; i < lines.length; ++i) {\n formatted += `\\n${spaces}${lines[i]}`;\n }\n\n return formatted;\n }),\n);\n\n// Service\n@injectable()\nexport class Logger {}\n\n// eslint-disable-next-line @typescript-eslint/no-empty-interface\nexport interface Logger extends winston.Logger {}\n\ncontainer.bind(Logger)\n .toDynamicValue((context) => {\n const config = context.container.get<GlobalConfig>(GLOBAL_CONFIG);\n\n return winston.createLogger({\n level: VERBOSITY_LEVEL[Math.min(config.verbose, 2)],\n format: winston.format.combine(\n winston.format.timestamp(),\n winston.format.ms(),\n ),\n transports: [\n new winston.transports.Console({\n format: consoleFormat\n })\n ]\n });\n })\n .inSingletonScope();\n"]}
1
+ {"version":3,"sources":["services/logger.service.ts"],"names":[],"mappings":"AAEA,OAAO,OAAO,MAAM,SAAS,CAAC;AAW9B,eAAO,MAAM,aAAa,wBAwBzB,CAAC;AAGF,qBACa,MAAM;CAAG;AAGtB,MAAM,WAAW,MAAO,SAAQ,OAAO,CAAC,MAAM;CAAG","file":"logger.service.d.ts","sourcesContent":["import chalk from 'chalk';\nimport { injectable } from 'inversify';\nimport winston from 'winston';\n\nimport { type GlobalConfig, GLOBAL_CONFIG, container } from './inversify.config';\n\n// Constants\nconst VERBOSITY_LEVEL: Record<number, string> = {\n 1: 'verbose',\n 2: 'debug',\n};\n\n// Utils\nexport const consoleFormat = winston.format.combine(\n winston.format.errors(),\n winston.format.colorize({\n message: true,\n colors: { debug: 'grey', verbose: 'blue', info: 'white', error: 'red' }\n }),\n winston.format.printf(({ label, message }) => {\n const lines = message.split('\\n');\n\n // Format\n let spaces = '';\n let formatted = lines[0];\n\n if (label) {\n spaces = ' '.repeat(label.length + 3);\n formatted = `${chalk.grey(`[${label}]`)} ${lines[0]}`;\n }\n\n for (let i = 1; i < lines.length; ++i) {\n formatted += `\\n${spaces}${lines[i]}`;\n }\n\n return formatted;\n }),\n);\n\n// Service\n@injectable()\nexport class Logger {}\n\n// eslint-disable-next-line @typescript-eslint/no-empty-interface\nexport interface Logger extends winston.Logger {}\n\ncontainer.bind(Logger)\n .toDynamicValue((context) => {\n const config = context.container.get<GlobalConfig>(GLOBAL_CONFIG);\n\n return winston.createLogger({\n level: VERBOSITY_LEVEL[Math.min(config.verbose, 2)],\n format: winston.format.combine(\n winston.format.timestamp(),\n ),\n transports: [\n new winston.transports.Console({\n format: consoleFormat\n })\n ]\n });\n })\n .inSingletonScope();\n"]}
@@ -40,14 +40,14 @@ const consoleFormat = _winston.default.format.combine(_winston.default.format.er
40
40
  info: 'white',
41
41
  error: 'red'
42
42
  }
43
- }), _winston.default.format.printf(({ label , message , ms })=>{
43
+ }), _winston.default.format.printf(({ label , message })=>{
44
44
  const lines = message.split('\n');
45
45
  // Format
46
46
  let spaces = '';
47
- let formatted = `${lines[0]} ${_chalk.default.magenta(ms)}`;
47
+ let formatted = lines[0];
48
48
  if (label) {
49
49
  spaces = ' '.repeat(label.length + 3);
50
- formatted = `${_chalk.default.grey(`[${label}]`)} ${lines[0]} ${_chalk.default.magenta(ms)}`;
50
+ formatted = `${_chalk.default.grey(`[${label}]`)} ${lines[0]}`;
51
51
  }
52
52
  for(let i = 1; i < lines.length; ++i){
53
53
  formatted += `\n${spaces}${lines[i]}`;
@@ -63,7 +63,7 @@ _inversifyConfig.container.bind(Logger).toDynamicValue((context)=>{
63
63
  const config = context.container.get(_inversifyConfig.GLOBAL_CONFIG);
64
64
  return _winston.default.createLogger({
65
65
  level: VERBOSITY_LEVEL[Math.min(config.verbose, 2)],
66
- format: _winston.default.format.combine(_winston.default.format.timestamp(), _winston.default.format.ms()),
66
+ format: _winston.default.format.combine(_winston.default.format.timestamp()),
67
67
  transports: [
68
68
  new _winston.default.transports.Console({
69
69
  format: consoleFormat
@@ -1 +1 @@
1
- {"version":3,"sources":["services/logger.service.js"],"sourcesContent":["import chalk from 'chalk';\nimport { injectable } from 'inversify';\nimport winston from 'winston';\n\nimport { type GlobalConfig, GLOBAL_CONFIG, container } from './inversify.config';\n\n// Constants\nconst VERBOSITY_LEVEL: Record<number, string> = {\n 1: 'verbose',\n 2: 'debug',\n};\n\n// Utils\nexport const consoleFormat = winston.format.combine(\n winston.format.errors(),\n winston.format.colorize({\n message: true,\n colors: { debug: 'grey', verbose: 'blue', info: 'white', error: 'red' }\n }),\n winston.format.printf(({ label, message, ms }) => {\n const lines = message.split('\\n');\n\n // Format\n let spaces = '';\n let formatted = `${lines[0]} ${chalk.magenta(ms)}`;\n\n if (label) {\n spaces = ' '.repeat(label.length + 3);\n formatted = `${chalk.grey(`[${label}]`)} ${lines[0]} ${chalk.magenta(ms)}`;\n }\n\n for (let i = 1; i < lines.length; ++i) {\n formatted += `\\n${spaces}${lines[i]}`;\n }\n\n return formatted;\n }),\n);\n\n// Service\n@injectable()\nexport class Logger {}\n\n// eslint-disable-next-line @typescript-eslint/no-empty-interface\nexport interface Logger extends winston.Logger {}\n\ncontainer.bind(Logger)\n .toDynamicValue((context) => {\n const config = context.container.get<GlobalConfig>(GLOBAL_CONFIG);\n\n return winston.createLogger({\n level: VERBOSITY_LEVEL[Math.min(config.verbose, 2)],\n format: winston.format.combine(\n winston.format.timestamp(),\n winston.format.ms(),\n ),\n transports: [\n new winston.transports.Console({\n format: consoleFormat\n })\n ]\n });\n })\n .inSingletonScope();\n"],"names":["consoleFormat","Logger","VERBOSITY_LEVEL","winston","format","combine","errors","colorize","message","colors","debug","verbose","info","error","printf","label","ms","lines","split","spaces","formatted","chalk","magenta","repeat","length","grey","i","injectable","container","bind","toDynamicValue","context","config","get","GLOBAL_CONFIG","createLogger","level","Math","min","timestamp","transports","Console","inSingletonScope"],"mappings":"AAAA;;;;;;;;;;;IAaaA,aAAa,MAAbA;IA4BAC,MAAM,MAANA;;4DAzCK;2BACS;8DACP;iCAEwC;;;;;;;;;;;;AAE5D,YAAY;AACZ,MAAMC,kBAA0C;IAC9C,GAAG;IACH,GAAG;AACL;AAGO,MAAMF,gBAAgBG,gBAAO,CAACC,MAAM,CAACC,OAAO,CACjDF,gBAAO,CAACC,MAAM,CAACE,MAAM,IACrBH,gBAAO,CAACC,MAAM,CAACG,QAAQ,CAAC;IACtBC,SAAS,IAAI;IACbC,QAAQ;QAAEC,OAAO;QAAQC,SAAS;QAAQC,MAAM;QAASC,OAAO;IAAM;AACxE,IACAV,gBAAO,CAACC,MAAM,CAACU,MAAM,CAAC,CAAC,EAAEC,MAAK,EAAEP,QAAO,EAAEQ,GAAE,EAAE,GAAK;IAChD,MAAMC,QAAQT,QAAQU,KAAK,CAAC;IAE5B,SAAS;IACT,IAAIC,SAAS;IACb,IAAIC,YAAY,CAAC,EAAEH,KAAK,CAAC,EAAE,CAAC,CAAC,EAAEI,cAAK,CAACC,OAAO,CAACN,IAAI,CAAC;IAElD,IAAID,OAAO;QACTI,SAAS,IAAII,MAAM,CAACR,MAAMS,MAAM,GAAG;QACnCJ,YAAY,CAAC,EAAEC,cAAK,CAACI,IAAI,CAAC,CAAC,CAAC,EAAEV,MAAM,CAAC,CAAC,EAAE,CAAC,EAAEE,KAAK,CAAC,EAAE,CAAC,CAAC,EAAEI,cAAK,CAACC,OAAO,CAACN,IAAI,CAAC;IAC5E,CAAC;IAED,IAAK,IAAIU,IAAI,GAAGA,IAAIT,MAAMO,MAAM,EAAE,EAAEE,EAAG;QACrCN,aAAa,CAAC,EAAE,EAAED,OAAO,EAAEF,KAAK,CAACS,EAAE,CAAC,CAAC;IACvC;IAEA,OAAON;AACT;IAKWnB,SAAN;AAAc;AAARA;IADZ0B,IAAAA,qBAAU;GACE1B;AAKb2B,0BAAS,CAACC,IAAI,CAAC5B,QACZ6B,cAAc,CAAC,CAACC,UAAY;IAC3B,MAAMC,SAASD,QAAQH,SAAS,CAACK,GAAG,CAAeC,8BAAa;IAEhE,OAAO/B,gBAAO,CAACgC,YAAY,CAAC;QAC1BC,OAAOlC,eAAe,CAACmC,KAAKC,GAAG,CAACN,OAAOrB,OAAO,EAAE,GAAG;QACnDP,QAAQD,gBAAO,CAACC,MAAM,CAACC,OAAO,CAC5BF,gBAAO,CAACC,MAAM,CAACmC,SAAS,IACxBpC,gBAAO,CAACC,MAAM,CAACY,EAAE;QAEnBwB,YAAY;YACV,IAAIrC,gBAAO,CAACqC,UAAU,CAACC,OAAO,CAAC;gBAC7BrC,QAAQJ;YACV;SACD;IACH;AACF,GACC0C,gBAAgB","file":"logger.service.js"}
1
+ {"version":3,"sources":["services/logger.service.js"],"sourcesContent":["import chalk from 'chalk';\nimport { injectable } from 'inversify';\nimport winston from 'winston';\n\nimport { type GlobalConfig, GLOBAL_CONFIG, container } from './inversify.config';\n\n// Constants\nconst VERBOSITY_LEVEL: Record<number, string> = {\n 1: 'verbose',\n 2: 'debug',\n};\n\n// Utils\nexport const consoleFormat = winston.format.combine(\n winston.format.errors(),\n winston.format.colorize({\n message: true,\n colors: { debug: 'grey', verbose: 'blue', info: 'white', error: 'red' }\n }),\n winston.format.printf(({ label, message }) => {\n const lines = message.split('\\n');\n\n // Format\n let spaces = '';\n let formatted = lines[0];\n\n if (label) {\n spaces = ' '.repeat(label.length + 3);\n formatted = `${chalk.grey(`[${label}]`)} ${lines[0]}`;\n }\n\n for (let i = 1; i < lines.length; ++i) {\n formatted += `\\n${spaces}${lines[i]}`;\n }\n\n return formatted;\n }),\n);\n\n// Service\n@injectable()\nexport class Logger {}\n\n// eslint-disable-next-line @typescript-eslint/no-empty-interface\nexport interface Logger extends winston.Logger {}\n\ncontainer.bind(Logger)\n .toDynamicValue((context) => {\n const config = context.container.get<GlobalConfig>(GLOBAL_CONFIG);\n\n return winston.createLogger({\n level: VERBOSITY_LEVEL[Math.min(config.verbose, 2)],\n format: winston.format.combine(\n winston.format.timestamp(),\n ),\n transports: [\n new winston.transports.Console({\n format: consoleFormat\n })\n ]\n });\n })\n .inSingletonScope();\n"],"names":["consoleFormat","Logger","VERBOSITY_LEVEL","winston","format","combine","errors","colorize","message","colors","debug","verbose","info","error","printf","label","lines","split","spaces","formatted","repeat","length","chalk","grey","i","injectable","container","bind","toDynamicValue","context","config","get","GLOBAL_CONFIG","createLogger","level","Math","min","timestamp","transports","Console","inSingletonScope"],"mappings":"AAAA;;;;;;;;;;;IAaaA,aAAa,MAAbA;IA4BAC,MAAM,MAANA;;4DAzCK;2BACS;8DACP;iCAEwC;;;;;;;;;;;;AAE5D,YAAY;AACZ,MAAMC,kBAA0C;IAC9C,GAAG;IACH,GAAG;AACL;AAGO,MAAMF,gBAAgBG,gBAAO,CAACC,MAAM,CAACC,OAAO,CACjDF,gBAAO,CAACC,MAAM,CAACE,MAAM,IACrBH,gBAAO,CAACC,MAAM,CAACG,QAAQ,CAAC;IACtBC,SAAS,IAAI;IACbC,QAAQ;QAAEC,OAAO;QAAQC,SAAS;QAAQC,MAAM;QAASC,OAAO;IAAM;AACxE,IACAV,gBAAO,CAACC,MAAM,CAACU,MAAM,CAAC,CAAC,EAAEC,MAAK,EAAEP,QAAO,EAAE,GAAK;IAC5C,MAAMQ,QAAQR,QAAQS,KAAK,CAAC;IAE5B,SAAS;IACT,IAAIC,SAAS;IACb,IAAIC,YAAYH,KAAK,CAAC,EAAE;IAExB,IAAID,OAAO;QACTG,SAAS,IAAIE,MAAM,CAACL,MAAMM,MAAM,GAAG;QACnCF,YAAY,CAAC,EAAEG,cAAK,CAACC,IAAI,CAAC,CAAC,CAAC,EAAER,MAAM,CAAC,CAAC,EAAE,CAAC,EAAEC,KAAK,CAAC,EAAE,CAAC,CAAC;IACvD,CAAC;IAED,IAAK,IAAIQ,IAAI,GAAGA,IAAIR,MAAMK,MAAM,EAAE,EAAEG,EAAG;QACrCL,aAAa,CAAC,EAAE,EAAED,OAAO,EAAEF,KAAK,CAACQ,EAAE,CAAC,CAAC;IACvC;IAEA,OAAOL;AACT;IAKWlB,SAAN;AAAc;AAARA;IADZwB,IAAAA,qBAAU;GACExB;AAKbyB,0BAAS,CAACC,IAAI,CAAC1B,QACZ2B,cAAc,CAAC,CAACC,UAAY;IAC3B,MAAMC,SAASD,QAAQH,SAAS,CAACK,GAAG,CAAeC,8BAAa;IAEhE,OAAO7B,gBAAO,CAAC8B,YAAY,CAAC;QAC1BC,OAAOhC,eAAe,CAACiC,KAAKC,GAAG,CAACN,OAAOnB,OAAO,EAAE,GAAG;QACnDP,QAAQD,gBAAO,CAACC,MAAM,CAACC,OAAO,CAC5BF,gBAAO,CAACC,MAAM,CAACiC,SAAS;QAE1BC,YAAY;YACV,IAAInC,gBAAO,CAACmC,UAAU,CAACC,OAAO,CAAC;gBAC7BnC,QAAQJ;YACV;SACD;IACH;AACF,GACCwC,gBAAgB","file":"logger.service.js"}
@@ -2,4 +2,6 @@ export * from './global-spinner';
2
2
  export * from './layout';
3
3
  export * from './list';
4
4
  export * from './static-logs';
5
+ export * from './tasks-spinner';
6
+ export * from './task-spinner';
5
7
  export * from './workspace-tree';
@@ -1 +1 @@
1
- {"version":3,"sources":["ui/index.ts"],"names":[],"mappings":"AAAA,cAAc,kBAAkB,CAAC;AACjC,cAAc,UAAU,CAAC;AACzB,cAAc,QAAQ,CAAC;AACvB,cAAc,eAAe,CAAC;AAC9B,cAAc,kBAAkB,CAAC","file":"index.d.ts","sourcesContent":["export * from './global-spinner';\nexport * from './layout';\nexport * from './list';\nexport * from './static-logs';\nexport * from './workspace-tree';\n"]}
1
+ {"version":3,"sources":["ui/index.ts"],"names":[],"mappings":"AAAA,cAAc,kBAAkB,CAAC;AACjC,cAAc,UAAU,CAAC;AACzB,cAAc,QAAQ,CAAC;AACvB,cAAc,eAAe,CAAC;AAC9B,cAAc,iBAAiB,CAAC;AAChC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,kBAAkB,CAAC","file":"index.d.ts","sourcesContent":["export * from './global-spinner';\nexport * from './layout';\nexport * from './list';\nexport * from './static-logs';\nexport * from './tasks-spinner';\nexport * from './task-spinner';\nexport * from './workspace-tree';\n"]}
package/dist/ui/index.js CHANGED
@@ -6,6 +6,8 @@ _exportStar(require("./global-spinner"), exports);
6
6
  _exportStar(require("./layout"), exports);
7
7
  _exportStar(require("./list"), exports);
8
8
  _exportStar(require("./static-logs"), exports);
9
+ _exportStar(require("./tasks-spinner"), exports);
10
+ _exportStar(require("./task-spinner"), exports);
9
11
  _exportStar(require("./workspace-tree"), exports);
10
12
  function _exportStar(from, to) {
11
13
  Object.keys(from).forEach(function(k) {
@@ -1 +1 @@
1
- {"version":3,"sources":["ui/index.js"],"sourcesContent":["export * from './global-spinner';\nexport * from './layout';\nexport * from './list';\nexport * from './static-logs';\nexport * from './workspace-tree';\n"],"names":[],"mappings":"AAAA;;;;oBAAc;oBACA;oBACA;oBACA;oBACA","file":"index.js"}
1
+ {"version":3,"sources":["ui/index.js"],"sourcesContent":["export * from './global-spinner';\nexport * from './layout';\nexport * from './list';\nexport * from './static-logs';\nexport * from './tasks-spinner';\nexport * from './task-spinner';\nexport * from './workspace-tree';\n"],"names":[],"mappings":"AAAA;;;;oBAAc;oBACA;oBACA;oBACA;oBACA;oBACA;oBACA","file":"index.js"}
@@ -0,0 +1,6 @@
1
+ import { Task } from '@jujulego/tasks';
2
+ import { FC } from 'react';
3
+ export interface TaskNameProps {
4
+ task: Task;
5
+ }
6
+ export declare const TaskName: FC<TaskNameProps>;
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["ui/task-name.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAe,MAAM,iBAAiB,CAAC;AAEpD,OAAO,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC;AAK3B,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,IAAI,CAAC;CACZ;AAQD,eAAO,MAAM,QAAQ,EAAE,EAAE,CAAC,aAAa,CAUtC,CAAC","file":"task-name.d.ts","sourcesContent":["import { Task, TaskContext } from '@jujulego/tasks';\nimport { Text } from 'ink';\nimport { FC } from 'react';\n\nimport { WorkspaceContext } from '../project';\n\n// Types\nexport interface TaskNameProps {\n task: Task;\n}\n\n// Utils\nfunction isWorkspaceCtx(ctx: Readonly<TaskContext>): ctx is Readonly<WorkspaceContext> {\n return 'workspace' in ctx;\n}\n\n// Components\nexport const TaskName: FC<TaskNameProps> = ({ task }) => {\n if (isWorkspaceCtx(task.context)) {\n return (\n <Text>\n Running <Text bold>{ task.context.script }</Text> in { task.context.workspace.name }\n </Text>\n );\n } else {\n return <Text>{ task.name }</Text>;\n }\n};\n"]}
@@ -0,0 +1,35 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ Object.defineProperty(exports, "TaskName", {
6
+ enumerable: true,
7
+ get: ()=>TaskName
8
+ });
9
+ const _jsxRuntime = require("react/jsx-runtime");
10
+ const _ink = require("ink");
11
+ // Utils
12
+ function isWorkspaceCtx(ctx) {
13
+ return 'workspace' in ctx;
14
+ }
15
+ const TaskName = ({ task })=>{
16
+ if (isWorkspaceCtx(task.context)) {
17
+ return /*#__PURE__*/ (0, _jsxRuntime.jsxs)(_ink.Text, {
18
+ children: [
19
+ "Running ",
20
+ /*#__PURE__*/ (0, _jsxRuntime.jsx)(_ink.Text, {
21
+ bold: true,
22
+ children: task.context.script
23
+ }),
24
+ " in ",
25
+ task.context.workspace.name
26
+ ]
27
+ });
28
+ } else {
29
+ return /*#__PURE__*/ (0, _jsxRuntime.jsx)(_ink.Text, {
30
+ children: task.name
31
+ });
32
+ }
33
+ };
34
+
35
+ //# sourceMappingURL=task-name.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["ui/task-name.js"],"sourcesContent":["import { Task, TaskContext } from '@jujulego/tasks';\nimport { Text } from 'ink';\nimport { FC } from 'react';\n\nimport { WorkspaceContext } from '../project';\n\n// Types\nexport interface TaskNameProps {\n task: Task;\n}\n\n// Utils\nfunction isWorkspaceCtx(ctx: Readonly<TaskContext>): ctx is Readonly<WorkspaceContext> {\n return 'workspace' in ctx;\n}\n\n// Components\nexport const TaskName: FC<TaskNameProps> = ({ task }) => {\n if (isWorkspaceCtx(task.context)) {\n return (\n <Text>\n Running <Text bold>{ task.context.script }</Text> in { task.context.workspace.name }\n </Text>\n );\n } else {\n return <Text>{ task.name }</Text>;\n }\n};\n"],"names":["TaskName","isWorkspaceCtx","ctx","task","context","Text","bold","script","workspace","name"],"mappings":"AAAA;;;;+BAiBaA;;aAAAA;;;qBAhBQ;AAUrB,QAAQ;AACR,SAASC,eAAeC,GAA0B,EAAqC;IACrF,OAAO,eAAeA;AACxB;AAGO,MAAMF,WAA8B,CAAC,EAAEG,KAAI,EAAE,GAAK;IACvD,IAAIF,eAAeE,KAAKC,OAAO,GAAG;QAChC,qBACE,sBAACC,SAAI;;gBAAC;8BACI,qBAACA,SAAI;oBAACC,IAAI;8BAAGH,KAAKC,OAAO,CAACG,MAAM;;gBAAS;gBAAMJ,KAAKC,OAAO,CAACI,SAAS,CAACC,IAAI;;;IAGxF,OAAO;QACL,qBAAO,qBAACJ,SAAI;sBAAGF,KAAKM,IAAI;;IAC1B,CAAC;AACH","file":"task-name.js"}
@@ -0,0 +1,6 @@
1
+ import { Task } from '@jujulego/tasks';
2
+ import { FC } from 'react';
3
+ export interface TaskSpinnerProps {
4
+ task: Task;
5
+ }
6
+ export declare const TaskSpinner: FC<TaskSpinnerProps>;
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["ui/task-spinner.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AAKvC,OAAO,EAAE,EAAE,EAA6B,MAAM,OAAO,CAAC;AAKtD,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,IAAI,CAAC;CACZ;AAGD,eAAO,MAAM,WAAW,EAAE,EAAE,CAAC,gBAAgB,CA0E5C,CAAC","file":"task-spinner.d.ts","sourcesContent":["import { waitForEvent } from '@jujulego/event-tree';\nimport { Task } from '@jujulego/tasks';\nimport { Text } from 'ink';\nimport Spinner from 'ink-spinner';\nimport symbols from 'log-symbols';\nimport ms from 'ms';\nimport { FC, useLayoutEffect, useState } from 'react';\n\nimport { TaskName } from './task-name';\n\n// Types\nexport interface TaskSpinnerProps {\n task: Task;\n}\n\n// Components\nexport const TaskSpinner: FC<TaskSpinnerProps> = ({ task }) => {\n // State\n const [status, setStatus] = useState(task.status);\n const [time, setTime] = useState(0);\n\n // Effects\n useLayoutEffect(() => {\n return task.subscribe('status', (event) => {\n setStatus(event.status);\n });\n }, [task]);\n\n useLayoutEffect(() => {\n const ctrl = new AbortController();\n\n (async () => {\n try {\n if (['blocked', 'ready']?.includes(task.status)) {\n await waitForEvent(task, 'status.running', { signal: ctrl.signal });\n }\n\n const start = Date.now();\n\n if (task.status === 'running') {\n await Promise.race([\n waitForEvent(task, 'status.done', { signal: ctrl.signal }),\n waitForEvent(task, 'status.failed', { signal: ctrl.signal })\n ]);\n }\n\n setTime(Date.now() - start);\n } catch (err) {\n if (err) {\n throw err;\n }\n }\n })();\n\n return () => ctrl.abort();\n }, [task]);\n\n // Render\n switch (status) {\n case 'blocked':\n case 'ready':\n return (\n <Text color=\"grey\">\n <Spinner type=\"line2\" />{' '}<TaskName task={task} />\n </Text>\n );\n\n case 'running':\n return (\n <Text>\n <Spinner />{' '}<TaskName task={task} />\n </Text>\n );\n\n case 'done':\n return (\n <Text>\n <Text color=\"green\">{ symbols.success }{' '}<TaskName task={task} /></Text>\n <Text color=\"magenta\">{' '}took { ms(time) }</Text>\n </Text>\n );\n\n case 'failed':\n return (\n <Text>\n <Text color=\"red\">{ symbols.error }{' '}<TaskName task={task} /></Text>\n <Text color=\"magenta\">{' '}took { ms(time) }</Text>\n </Text>\n );\n }\n};\n"]}
@@ -0,0 +1,143 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ Object.defineProperty(exports, "TaskSpinner", {
6
+ enumerable: true,
7
+ get: ()=>TaskSpinner
8
+ });
9
+ const _jsxRuntime = require("react/jsx-runtime");
10
+ const _eventTree = require("@jujulego/event-tree");
11
+ const _ink = require("ink");
12
+ const _inkSpinner = /*#__PURE__*/ _interopRequireDefault(require("ink-spinner"));
13
+ const _logSymbols = /*#__PURE__*/ _interopRequireDefault(require("log-symbols"));
14
+ const _ms = /*#__PURE__*/ _interopRequireDefault(require("ms"));
15
+ const _react = require("react");
16
+ const _taskName = require("./task-name");
17
+ function _interopRequireDefault(obj) {
18
+ return obj && obj.__esModule ? obj : {
19
+ default: obj
20
+ };
21
+ }
22
+ const TaskSpinner = ({ task })=>{
23
+ // State
24
+ const [status, setStatus] = (0, _react.useState)(task.status);
25
+ const [time, setTime] = (0, _react.useState)(0);
26
+ // Effects
27
+ (0, _react.useLayoutEffect)(()=>{
28
+ return task.subscribe('status', (event)=>{
29
+ setStatus(event.status);
30
+ });
31
+ }, [
32
+ task
33
+ ]);
34
+ (0, _react.useLayoutEffect)(()=>{
35
+ const ctrl = new AbortController();
36
+ (async ()=>{
37
+ try {
38
+ if ([
39
+ 'blocked',
40
+ 'ready'
41
+ ]?.includes(task.status)) {
42
+ await (0, _eventTree.waitForEvent)(task, 'status.running', {
43
+ signal: ctrl.signal
44
+ });
45
+ }
46
+ const start = Date.now();
47
+ if (task.status === 'running') {
48
+ await Promise.race([
49
+ (0, _eventTree.waitForEvent)(task, 'status.done', {
50
+ signal: ctrl.signal
51
+ }),
52
+ (0, _eventTree.waitForEvent)(task, 'status.failed', {
53
+ signal: ctrl.signal
54
+ })
55
+ ]);
56
+ }
57
+ setTime(Date.now() - start);
58
+ } catch (err) {
59
+ if (err) {
60
+ throw err;
61
+ }
62
+ }
63
+ })();
64
+ return ()=>ctrl.abort();
65
+ }, [
66
+ task
67
+ ]);
68
+ // Render
69
+ switch(status){
70
+ case 'blocked':
71
+ case 'ready':
72
+ return /*#__PURE__*/ (0, _jsxRuntime.jsxs)(_ink.Text, {
73
+ color: "grey",
74
+ children: [
75
+ /*#__PURE__*/ (0, _jsxRuntime.jsx)(_inkSpinner.default, {
76
+ type: "line2"
77
+ }),
78
+ ' ',
79
+ /*#__PURE__*/ (0, _jsxRuntime.jsx)(_taskName.TaskName, {
80
+ task: task
81
+ })
82
+ ]
83
+ });
84
+ case 'running':
85
+ return /*#__PURE__*/ (0, _jsxRuntime.jsxs)(_ink.Text, {
86
+ children: [
87
+ /*#__PURE__*/ (0, _jsxRuntime.jsx)(_inkSpinner.default, {}),
88
+ ' ',
89
+ /*#__PURE__*/ (0, _jsxRuntime.jsx)(_taskName.TaskName, {
90
+ task: task
91
+ })
92
+ ]
93
+ });
94
+ case 'done':
95
+ return /*#__PURE__*/ (0, _jsxRuntime.jsxs)(_ink.Text, {
96
+ children: [
97
+ /*#__PURE__*/ (0, _jsxRuntime.jsxs)(_ink.Text, {
98
+ color: "green",
99
+ children: [
100
+ _logSymbols.default.success,
101
+ ' ',
102
+ /*#__PURE__*/ (0, _jsxRuntime.jsx)(_taskName.TaskName, {
103
+ task: task
104
+ })
105
+ ]
106
+ }),
107
+ /*#__PURE__*/ (0, _jsxRuntime.jsxs)(_ink.Text, {
108
+ color: "magenta",
109
+ children: [
110
+ ' ',
111
+ "took ",
112
+ (0, _ms.default)(time)
113
+ ]
114
+ })
115
+ ]
116
+ });
117
+ case 'failed':
118
+ return /*#__PURE__*/ (0, _jsxRuntime.jsxs)(_ink.Text, {
119
+ children: [
120
+ /*#__PURE__*/ (0, _jsxRuntime.jsxs)(_ink.Text, {
121
+ color: "red",
122
+ children: [
123
+ _logSymbols.default.error,
124
+ ' ',
125
+ /*#__PURE__*/ (0, _jsxRuntime.jsx)(_taskName.TaskName, {
126
+ task: task
127
+ })
128
+ ]
129
+ }),
130
+ /*#__PURE__*/ (0, _jsxRuntime.jsxs)(_ink.Text, {
131
+ color: "magenta",
132
+ children: [
133
+ ' ',
134
+ "took ",
135
+ (0, _ms.default)(time)
136
+ ]
137
+ })
138
+ ]
139
+ });
140
+ }
141
+ };
142
+
143
+ //# sourceMappingURL=task-spinner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["ui/task-spinner.js"],"sourcesContent":["import { waitForEvent } from '@jujulego/event-tree';\nimport { Task } from '@jujulego/tasks';\nimport { Text } from 'ink';\nimport Spinner from 'ink-spinner';\nimport symbols from 'log-symbols';\nimport ms from 'ms';\nimport { FC, useLayoutEffect, useState } from 'react';\n\nimport { TaskName } from './task-name';\n\n// Types\nexport interface TaskSpinnerProps {\n task: Task;\n}\n\n// Components\nexport const TaskSpinner: FC<TaskSpinnerProps> = ({ task }) => {\n // State\n const [status, setStatus] = useState(task.status);\n const [time, setTime] = useState(0);\n\n // Effects\n useLayoutEffect(() => {\n return task.subscribe('status', (event) => {\n setStatus(event.status);\n });\n }, [task]);\n\n useLayoutEffect(() => {\n const ctrl = new AbortController();\n\n (async () => {\n try {\n if (['blocked', 'ready']?.includes(task.status)) {\n await waitForEvent(task, 'status.running', { signal: ctrl.signal });\n }\n\n const start = Date.now();\n\n if (task.status === 'running') {\n await Promise.race([\n waitForEvent(task, 'status.done', { signal: ctrl.signal }),\n waitForEvent(task, 'status.failed', { signal: ctrl.signal })\n ]);\n }\n\n setTime(Date.now() - start);\n } catch (err) {\n if (err) {\n throw err;\n }\n }\n })();\n\n return () => ctrl.abort();\n }, [task]);\n\n // Render\n switch (status) {\n case 'blocked':\n case 'ready':\n return (\n <Text color=\"grey\">\n <Spinner type=\"line2\" />{' '}<TaskName task={task} />\n </Text>\n );\n\n case 'running':\n return (\n <Text>\n <Spinner />{' '}<TaskName task={task} />\n </Text>\n );\n\n case 'done':\n return (\n <Text>\n <Text color=\"green\">{ symbols.success }{' '}<TaskName task={task} /></Text>\n <Text color=\"magenta\">{' '}took { ms(time) }</Text>\n </Text>\n );\n\n case 'failed':\n return (\n <Text>\n <Text color=\"red\">{ symbols.error }{' '}<TaskName task={task} /></Text>\n <Text color=\"magenta\">{' '}took { ms(time) }</Text>\n </Text>\n );\n }\n};\n"],"names":["TaskSpinner","task","status","setStatus","useState","time","setTime","useLayoutEffect","subscribe","event","ctrl","AbortController","includes","waitForEvent","signal","start","Date","now","Promise","race","err","abort","Text","color","Spinner","type","TaskName","symbols","success","ms","error"],"mappings":"AAAA;;;;+BAgBaA;;aAAAA;;;2BAhBgB;qBAER;iEACD;iEACA;yDACL;uBAC+B;0BAErB;;;;;;AAQlB,MAAMA,cAAoC,CAAC,EAAEC,KAAI,EAAE,GAAK;IAC7D,QAAQ;IACR,MAAM,CAACC,QAAQC,UAAU,GAAGC,IAAAA,eAAQ,EAACH,KAAKC,MAAM;IAChD,MAAM,CAACG,MAAMC,QAAQ,GAAGF,IAAAA,eAAQ,EAAC;IAEjC,UAAU;IACVG,IAAAA,sBAAe,EAAC,IAAM;QACpB,OAAON,KAAKO,SAAS,CAAC,UAAU,CAACC,QAAU;YACzCN,UAAUM,MAAMP,MAAM;QACxB;IACF,GAAG;QAACD;KAAK;IAETM,IAAAA,sBAAe,EAAC,IAAM;QACpB,MAAMG,OAAO,IAAIC;QAEhB,CAAA,UAAY;YACX,IAAI;gBACF,IAAI;oBAAC;oBAAW;iBAAQ,EAAEC,SAASX,KAAKC,MAAM,GAAG;oBAC/C,MAAMW,IAAAA,uBAAY,EAACZ,MAAM,kBAAkB;wBAAEa,QAAQJ,KAAKI,MAAM;oBAAC;gBACnE,CAAC;gBAED,MAAMC,QAAQC,KAAKC,GAAG;gBAEtB,IAAIhB,KAAKC,MAAM,KAAK,WAAW;oBAC7B,MAAMgB,QAAQC,IAAI,CAAC;wBACjBN,IAAAA,uBAAY,EAACZ,MAAM,eAAe;4BAAEa,QAAQJ,KAAKI,MAAM;wBAAC;wBACxDD,IAAAA,uBAAY,EAACZ,MAAM,iBAAiB;4BAAEa,QAAQJ,KAAKI,MAAM;wBAAC;qBAC3D;gBACH,CAAC;gBAEDR,QAAQU,KAAKC,GAAG,KAAKF;YACvB,EAAE,OAAOK,KAAK;gBACZ,IAAIA,KAAK;oBACP,MAAMA,IAAI;gBACZ,CAAC;YACH;QACF,CAAA;QAEA,OAAO,IAAMV,KAAKW,KAAK;IACzB,GAAG;QAACpB;KAAK;IAET,SAAS;IACT,OAAQC;QACN,KAAK;QACL,KAAK;YACH,qBACE,sBAACoB,SAAI;gBAACC,OAAM;;kCACV,qBAACC,mBAAO;wBAACC,MAAK;;oBAAW;kCAAI,qBAACC,kBAAQ;wBAACzB,MAAMA;;;;QAInD,KAAK;YACH,qBACE,sBAACqB,SAAI;;kCACH,qBAACE,mBAAO;oBAAI;kCAAI,qBAACE,kBAAQ;wBAACzB,MAAMA;;;;QAItC,KAAK;YACH,qBACE,sBAACqB,SAAI;;kCACH,sBAACA,SAAI;wBAACC,OAAM;;4BAAUI,mBAAO,CAACC,OAAO;4BAAG;0CAAI,qBAACF,kBAAQ;gCAACzB,MAAMA;;;;kCAC5D,sBAACqB,SAAI;wBAACC,OAAM;;4BAAW;4BAAI;4BAAOM,IAAAA,WAAE,EAACxB;;;;;QAI3C,KAAK;YACH,qBACE,sBAACiB,SAAI;;kCACH,sBAACA,SAAI;wBAACC,OAAM;;4BAAQI,mBAAO,CAACG,KAAK;4BAAG;0CAAI,qBAACJ,kBAAQ;gCAACzB,MAAMA;;;;kCACxD,sBAACqB,SAAI;wBAACC,OAAM;;4BAAW;4BAAI;4BAAOM,IAAAA,WAAE,EAACxB;;;;;IAG7C;AACF","file":"task-spinner.js"}
@@ -0,0 +1,6 @@
1
+ import { TaskManager } from '@jujulego/tasks';
2
+ import { FC } from 'react';
3
+ export interface TasksSpinnerProps {
4
+ manager: TaskManager;
5
+ }
6
+ export declare const TasksSpinner: FC<TasksSpinnerProps>;
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["ui/tasks-spinner.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAC9C,OAAO,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC;AAK3B,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,WAAW,CAAC;CACtB;AAGD,eAAO,MAAM,YAAY,EAAE,EAAE,CAAC,iBAAiB,CAM9C,CAAC","file":"tasks-spinner.d.ts","sourcesContent":["import { TaskManager } from '@jujulego/tasks';\nimport { FC } from 'react';\n\nimport { TaskSpinner } from './task-spinner';\n\n// Types\nexport interface TasksSpinnerProps {\n manager: TaskManager;\n}\n\n// Components\nexport const TasksSpinner: FC<TasksSpinnerProps> = ({ manager }) => (\n <>\n { manager.tasks.map((task, idx) => (\n <TaskSpinner key={idx} task={task}/>\n )) }\n </>\n);\n"]}
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ Object.defineProperty(exports, "TasksSpinner", {
6
+ enumerable: true,
7
+ get: ()=>TasksSpinner
8
+ });
9
+ const _jsxRuntime = require("react/jsx-runtime");
10
+ const _taskSpinner = require("./task-spinner");
11
+ const TasksSpinner = ({ manager })=>/*#__PURE__*/ (0, _jsxRuntime.jsx)(_jsxRuntime.Fragment, {
12
+ children: manager.tasks.map((task, idx)=>/*#__PURE__*/ (0, _jsxRuntime.jsx)(_taskSpinner.TaskSpinner, {
13
+ task: task
14
+ }, idx))
15
+ });
16
+
17
+ //# sourceMappingURL=tasks-spinner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["ui/tasks-spinner.js"],"sourcesContent":["import { TaskManager } from '@jujulego/tasks';\nimport { FC } from 'react';\n\nimport { TaskSpinner } from './task-spinner';\n\n// Types\nexport interface TasksSpinnerProps {\n manager: TaskManager;\n}\n\n// Components\nexport const TasksSpinner: FC<TasksSpinnerProps> = ({ manager }) => (\n <>\n { manager.tasks.map((task, idx) => (\n <TaskSpinner key={idx} task={task}/>\n )) }\n </>\n);\n"],"names":["TasksSpinner","manager","tasks","map","task","idx","TaskSpinner"],"mappings":"AAAA;;;;+BAWaA;;aAAAA;;;6BARe;AAQrB,MAAMA,eAAsC,CAAC,EAAEC,QAAO,EAAE,iBAC7D;kBACIA,QAAQC,KAAK,CAACC,GAAG,CAAC,CAACC,MAAMC,oBACzB,qBAACC,wBAAW;gBAAWF,MAAMA;eAAXC","file":"tasks-spinner.js"}
package/package.json CHANGED
@@ -1,11 +1,10 @@
1
1
  {
2
2
  "name": "@jujulego/jill",
3
- "version": "2.0.0-alpha.3",
3
+ "version": "2.0.0-alpha.5",
4
4
  "license": "MIT",
5
5
  "repository": {
6
6
  "type": "git",
7
- "url": "https://github.com/Jujulego/jill",
8
- "directory": "packages/core"
7
+ "url": "https://github.com/Jujulego/jill"
9
8
  },
10
9
  "files": [
11
10
  "bin",
@@ -38,6 +37,7 @@
38
37
  "inversify": "^6.0.1",
39
38
  "inversify-inject-decorators": "^3.1.0",
40
39
  "log-symbols": "^4.1.0",
40
+ "ms": "^2.1.3",
41
41
  "normalize-package-data": "^4.0.0",
42
42
  "react": "^17.0.2",
43
43
  "reflect-metadata": "^0.1.13",
@@ -58,6 +58,7 @@
58
58
  "@types/gulp": "4.0.9",
59
59
  "@types/gulp-sourcemaps": "0.0.35",
60
60
  "@types/jest": "28.1.3",
61
+ "@types/ms": "0.7.31",
61
62
  "@types/node": "16.11.64",
62
63
  "@types/normalize-package-data": "2.4.1",
63
64
  "@types/react": "17.0.50",