tungsten 0.2.6 → 0.2.7

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.
@@ -53,6 +53,7 @@ type Opts = {
53
53
  codeDir: string;
54
54
  buildLocation: string;
55
55
  buildCodeLocation: string;
56
+ packagesCacheLocation: string;
56
57
  oldDependencyGraph: DependencyGraph;
57
58
  dependencyGraph: DependencyGraph;
58
59
  importAliases: {
@@ -1 +1 @@
1
- {"version":3,"file":"BabelTransformPackageImports.d.ts","sourceRoot":"","sources":["../../src/babelPlugins/BabelTransformPackageImports.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"BabelTransformPackageImports.d.ts","sourceRoot":"","sources":["../../src/babelPlugins/BabelTransformPackageImports.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAA;AAQrD,OAAO,EAGH,QAAQ,EACX,MAAM,aAAa,CAAA;AACpB,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AA6B5C,MAAM,MAAM,QAAQ,GAAG,KAAK,GAAG,KAAK,GAAG,SAAS,GAAG,SAAS,GAAG,MAAM,CAAA;AAErE,MAAM,MAAM,QAAQ,GAAG;IACnB,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,MAAM,CAAA;IACf,cAAc,EAAE,MAAM,CAAA;IACtB,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,MAAM,CAAA;IACjB,WAAW,EAAE,MAAM,CAAA;IACnB,IAAI,EAAE,QAAQ,CAAA;IACd,WAAW,EAAE,WAAW,CAAA;CAC3B,CAAA;AAED,MAAM,MAAM,WAAW,GAAG,KAAK,GAAG,KAAK,GAAG,SAAS,CAAA;AAEnD,MAAM,MAAM,WAAW,GAAG;IACtB,UAAU,EAAE,MAAM,CAAA;IAClB,WAAW,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,CAAA;IACtC,WAAW,EAAE,MAAM,CAAA;IACnB,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,EAAE,WAAW,CAAA;IACjB,iBAAiB,EAAE,MAAM,CAAA;IACzB,aAAa,EAAE,MAAM,CAAA;IACrB,aAAa,EAAE,MAAM,CAAA;CACxB,CAAA;AAGD,MAAM,MAAM,WAAW,GAAG;IACtB,CAAC,GAAG,EAAC,MAAM,GAAG,WAAW,CAAA;CAC5B,CAAA;AAED,MAAM,MAAM,cAAc,GAAG,WAAW,GAAG;IACvC,KAAK,EAAE,MAAM,EAAE,CAAA;CAClB,CAAA;AAED,MAAM,MAAM,cAAc,GAAG;IACzB,CAAC,GAAG,EAAC,MAAM,GAAG,cAAc,CAAA;CAC/B,CAAA;AAED,MAAM,MAAM,mBAAmB,GAAG;IAC9B,IAAI,EAAE,QAAQ,CAAA;IACd,gBAAgB,EAAE,MAAM,CAAA;IACxB,aAAa,EAAE,MAAM,CAAA;IACrB,aAAa,EAAE,MAAM,CAAA;IACrB,YAAY,CAAC,EAAE,YAAY,CAAA;CAC9B,CAAA;AAED,MAAM,MAAM,iCAAiC,GAAG,mBAAmB,GAAG;IAClE,cAAc,EAAE,MAAM,CAAA;CACzB,CAAA;AAED,MAAM,MAAM,eAAe,GAAG;IAC1B,CAAC,GAAG,EAAE,MAAM,GAAG,mBAAmB,CAAA;CACrC,CAAA;AAED,MAAM,MAAM,YAAY,GAAG,MAAM,EAAE,CAAA;AAEnC,KAAK,IAAI,GAAG;IACR,UAAU,EAAE,MAAM,CAAA;IAClB,OAAO,EAAE,MAAM,CAAA;IACf,aAAa,EAAE,MAAM,CAAA;IACrB,iBAAiB,EAAE,MAAM,CAAA;IACzB,qBAAqB,EAAE,MAAM,CAAA;IAC7B,kBAAkB,EAAE,eAAe,CAAA;IACnC,eAAe,EAAE,eAAe,CAAA;IAChC,aAAa,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,CAAA;IAGxC,QAAQ,EAAE,OAAO,CAAC,WAAW,GAAG,SAAS,CAAC,EAAE,CAAA;CAC/C,CAAA;AAED,MAAM,MAAM,oBAAoB,GAAG,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAA;AAC3D,MAAM,MAAM,qBAAqB,GAAG,CAAC,IAAI,EAAE,MAAM,KAAK,WAAW,CAAA;AACjE,MAAM,MAAM,oCAAoC,GAC1C,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,gBAAgB,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,KAAK,MAAM,CAAA;AACpG,MAAM,MAAM,kCAAkC,GACxC,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAmC,MAAM,CAAA;AAChF,MAAM,MAAM,uCAAuC,GAC7C,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAmC,MAAM,CAAA;AAChF,MAAM,MAAM,oBAAoB,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,WAAW,KAAK,MAAM,CAAA;AACrF,MAAM,MAAM,gBAAgB,GAAG,CAAC,UAAU,EAAE,MAAM,EAAE,kBAAkB,EAAE,MAAM,KAAK,MAAM,CAAA;AA0CzF,wBAAgB,gCAAgC,CAAC,IAAI,EAAE,IAAI;eAgwBpC,SAAS;;kCAiBmB,QAAQ,CAAC,iBAAiB,CAAC;;;EAyH7E"}
@@ -21,7 +21,7 @@ lexerInit();
21
21
  import { MakeBabelTransformCjsToFunction } from "./BabelTransformCjsToFunction.js";
22
22
  import { MakeBabelTransformDependencyImportsEsm } from "./transformPackageImports/BabelTransformDependencyImportsEsm.js";
23
23
  import { MakeBabelTransformDependencyImportsCjs } from "./transformPackageImports/BabelTransformDependencyImportsCjs.js";
24
- import { frameworkDistFolder, packageName as frameworkPackageName, packageName, packagesCacheFolder, packagesFolder /*, packagesCacheInfoName*/ } from "../settings.js";
24
+ import { frameworkDistFolder, packageName as frameworkPackageName, packageName, packagesFolder /*, packagesCacheInfoName*/ } from "../settings.js";
25
25
  import { findProjectDir } from "../findProjectDir.js";
26
26
  import { cliError, cliWarn, cliNote, cliInfo, cliNews } from "../cliOutput.js";
27
27
  import { isBareImport } from "./isBareImport.js";
@@ -45,7 +45,7 @@ export function MakeBabelTransformPackageImports(opts) {
45
45
  const buildLocation = opts.buildLocation;
46
46
  const packagesLocation = join(buildLocation, packagesFolder);
47
47
  // get info about the packages cache
48
- const packagesCacheLocation = join(opts.projectDir, packagesCacheFolder);
48
+ const packagesCacheLocation = opts.packagesCacheLocation;
49
49
  const packages = {};
50
50
  const nonEsmPackages = {};
51
51
  function applyImportAliases(location, fileType) {
@@ -1 +1 @@
1
- {"version":3,"file":"compile.d.ts","sourceRoot":"","sources":["../../../src/bin/commands/compile.ts"],"names":[],"mappings":"AA4JA,OAAO,EAAE,CAAA"}
1
+ {"version":3,"file":"compile.d.ts","sourceRoot":"","sources":["../../../src/bin/commands/compile.ts"],"names":[],"mappings":"AAyPA,OAAO,EAAE,CAAA"}
@@ -1,4 +1,5 @@
1
- import { join } from 'path';
1
+ import { dirname, join, resolve } from 'path';
2
+ import { promises as fsPromises } from 'fs';
2
3
  import rmfr from 'rmfr';
3
4
  import { compileJavascript } from "../../build/compileJavascript.js";
4
5
  import { compileStyles } from "../../build/compileStyles.js";
@@ -17,19 +18,38 @@ const targetOptions = {
17
18
  '--public': 'public'
18
19
  };
19
20
  const args = process.argv.slice(3);
21
+ function optionValue(option) {
22
+ const position = args.indexOf(option);
23
+ if (position === -1) return undefined;
24
+ const value = args[position + 1];
25
+ if (value === undefined || value.startsWith('--')) {
26
+ cliError(`${option} requires a path`);
27
+ process.exit(1);
28
+ }
29
+ return value;
30
+ }
20
31
  if (args.includes('--help') || args.includes('-h')) {
21
- cliOut('Usage: tungsten compile [targets] [--all] [--watch] [--no-clean]');
32
+ cliOut('Usage: tungsten compile [targets] [--all] [--watch] [--no-clean] [--output <dir>]');
22
33
  cliOut('Targets: --js, --css, --client, --assets, --public');
23
34
  cliOut('With no target options, all targets are compiled.');
35
+ cliOut('Options: --output <dir>, --ready-file <file>, --quiet');
24
36
  process.exit(0);
25
37
  }
26
- const commandOptions = new Set(['--all', '--watch', '--no-clean']);
27
- const unknownOptions = args.filter(arg => !(arg in targetOptions) && !commandOptions.has(arg));
38
+ const commandOptions = new Set(['--all', '--watch', '--no-clean', '--quiet']);
39
+ const valueOptions = new Set(['--output', '--ready-file']);
40
+ const optionValues = new Set();
41
+ for (const option of valueOptions) {
42
+ const position = args.indexOf(option);
43
+ if (position !== -1 && args[position + 1] !== undefined) optionValues.add(args[position + 1]);
44
+ }
45
+ const unknownOptions = args.filter(arg => !(arg in targetOptions) && !commandOptions.has(arg) && !valueOptions.has(arg) && !optionValues.has(arg));
28
46
  if (unknownOptions.length > 0) {
29
47
  cliError(`Unknown compile option${unknownOptions.length === 1 ? '' : 's'}: ${unknownOptions.join(', ')}`);
30
- cliOut('Usage: tungsten compile [targets] [--all] [--watch] [--no-clean]');
48
+ cliOut('Usage: tungsten compile [targets] [--all] [--watch] [--no-clean] [--output <dir>]');
31
49
  process.exit(1);
32
50
  }
51
+ const outputOption = optionValue('--output');
52
+ const readyFileOption = optionValue('--ready-file');
33
53
  const requestedTargets = new Set();
34
54
  for (const arg of args) {
35
55
  const target = targetOptions[arg];
@@ -38,17 +58,43 @@ for (const arg of args) {
38
58
  const targets = requestedTargets.size === 0 || args.includes('--all') ? new Set(['js', 'css', 'client', 'assets', 'public']) : requestedTargets;
39
59
  const watch = args.includes('--watch');
40
60
  const clean = !args.includes('--no-clean');
61
+ const quiet = args.includes('--quiet');
41
62
  const projectDir = process.cwd();
42
63
  const config = await getUserConfig();
43
64
  const codeLocation = join(projectDir, config.codeDir);
44
65
  const relSourceDir = config.sourceDir !== undefined && config.sourceDir !== '' ? config.sourceDir : config.codeDir;
45
66
  const sourceLocation = join(projectDir, relSourceDir);
46
67
  const styleImportBase = config.styleImportBase !== undefined ? join(sourceLocation, config.styleImportBase) : sourceLocation;
47
- const buildLocation = join(projectDir, devBuildOuterFolder);
68
+ const buildLocation = outputOption !== undefined ? resolve(projectDir, outputOption) : join(projectDir, devBuildOuterFolder);
48
69
  const buildCodeLocation = join(buildLocation, buildCodeSubPath);
70
+ const packagesCacheLocation = outputOption !== undefined ? join(buildLocation, '.packagesCache') : join(projectDir, packagesCacheFolder);
71
+ const readyFileLocation = readyFileOption !== undefined ? resolve(projectDir, readyFileOption) : undefined;
72
+ if (buildLocation.toLowerCase() === resolve(projectDir).toLowerCase()) {
73
+ cliError('Compile output cannot be the project root');
74
+ process.exit(1);
75
+ }
76
+ async function clearReadyFile() {
77
+ if (readyFileLocation !== undefined) await rmfr(readyFileLocation);
78
+ }
79
+ async function markReady() {
80
+ if (readyFileLocation === undefined) return;
81
+ await fsPromises.mkdir(dirname(readyFileLocation), {
82
+ recursive: true
83
+ });
84
+ const temporaryLocation = `${readyFileLocation}.${process.pid}.tmp`;
85
+ await fsPromises.writeFile(temporaryLocation, JSON.stringify({
86
+ ready: true,
87
+ output: buildLocation,
88
+ targets: [...targets],
89
+ updatedAt: new Date().toISOString()
90
+ }));
91
+ await rmfr(readyFileLocation);
92
+ await fsPromises.rename(temporaryLocation, readyFileLocation);
93
+ }
94
+ await clearReadyFile();
49
95
  const cleanTasks = [];
50
96
  if (clean && targets.has('js')) {
51
- cleanTasks.push(rmfr(buildCodeLocation), rmfr(join(buildLocation, componentCssFolder)), rmfr(join(buildLocation, packagesFolder)), rmfr(join(projectDir, packagesCacheFolder)));
97
+ cleanTasks.push(rmfr(buildCodeLocation), rmfr(join(buildLocation, componentCssFolder)), rmfr(join(buildLocation, packagesFolder)), rmfr(packagesCacheLocation));
52
98
  }
53
99
  if (clean && targets.has('css')) {
54
100
  cleanTasks.push(rmfr(join(buildLocation, staticFolder)));
@@ -63,15 +109,32 @@ if (clean) {
63
109
  await Promise.all(cleanTasks);
64
110
  }
65
111
  const compilationTasks = [];
112
+ let javascriptInitialSuccess = true;
66
113
  if (targets.has('js')) {
67
- compilationTasks.push(compileJavascript(projectDir, config, codeLocation, sourceLocation, styleImportBase, buildLocation, buildCodeLocation, 'dev', watch));
114
+ const javascriptTask = compileJavascript(projectDir, config, codeLocation, sourceLocation, styleImportBase, buildLocation, buildCodeLocation, 'dev', watch, {
115
+ quiet,
116
+ packagesCacheLocation,
117
+ onCycleComplete: watch ? async cycle => {
118
+ if (cycle.success) {
119
+ await markReady();
120
+ cliNews(`Compile cycle complete: js${cycle.file ? ` (${cycle.file})` : ''}`);
121
+ } else {
122
+ await clearReadyFile();
123
+ cliError(`Compile cycle failed: js${cycle.file ? ` (${cycle.file})` : ''}`);
124
+ }
125
+ } : undefined
126
+ });
127
+ compilationTasks.push(javascriptTask.then(result => {
128
+ javascriptInitialSuccess = result.initialSuccess;
129
+ return result;
130
+ }));
68
131
  }
69
132
  if (targets.has('css')) {
70
133
  compilationTasks.push(compileStyles(projectDir, config, styleImportBase, buildLocation, watch));
71
134
  }
72
135
  if (targets.has('client')) {
73
- compilationTasks.push(createInstanceConfigFile(config, 'dev'));
74
- compilationTasks.push(createClientFiles(config, 'dev'));
136
+ compilationTasks.push(createInstanceConfigFile(config, 'dev', buildLocation));
137
+ compilationTasks.push(createClientFiles(config, 'dev', buildLocation));
75
138
  }
76
139
  if (targets.has('assets')) {
77
140
  const assetsTask = copyAssets(projectDir, config, buildLocation, watch);
@@ -80,10 +143,21 @@ if (targets.has('assets')) {
80
143
  if (targets.has('public')) {
81
144
  compilationTasks.push(copyPublicFiles(projectDir, config, buildLocation, watch));
82
145
  }
83
- await Promise.all(compilationTasks);
84
- cliNews(`Compile complete: ${[...targets].join(', ')}`);
146
+ const compilationResults = await Promise.allSettled(compilationTasks);
147
+ const failures = compilationResults.filter(result => result.status === 'rejected').map(result => result.reason);
148
+ const initialSuccess = failures.length === 0 && javascriptInitialSuccess;
149
+ if (initialSuccess) {
150
+ await markReady();
151
+ cliNews(`Compile complete: ${[...targets].join(', ')}`);
152
+ } else {
153
+ await clearReadyFile();
154
+ cliError(`Compile failed: ${[...targets].join(', ')}`);
155
+ }
156
+ if (!watch && !initialSuccess) {
157
+ throw new AggregateError(failures, 'Compilation failed');
158
+ }
85
159
  if (watch && (targets.has('js') || targets.has('css') || targets.has('assets') || targets.has('public'))) {
86
- cliNews('Watching for changes');
160
+ cliNews(initialSuccess ? 'Watching for changes' : 'Watching for changes; waiting for a successful cycle');
87
161
  } else {
88
162
  // The underlying development compilers watch after their initial pass.
89
163
  // End them when this command is being used for one-shot test preparation.
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=compile.sxyt.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compile.sxyt.d.ts","sourceRoot":"","sources":["../../../src/bin/commands/compile.sxyt.ts"],"names":[],"mappings":""}
@@ -0,0 +1,61 @@
1
+ import { execFile } from 'child_process';
2
+ import { mkdtemp, readFile, rm, writeFile } from 'fs/promises';
3
+ import { tmpdir } from 'os';
4
+ import { join } from 'path';
5
+ import { promisify } from 'util';
6
+ import { expect } from 'chai';
7
+ import { describe } from 'sxy-test-runner';
8
+ import { findProjectDir } from "../../findProjectDir.js";
9
+ const execFileAsync = promisify(execFile);
10
+ describe('tungsten compile', ({
11
+ it
12
+ }) => {
13
+ it('exits non-zero and does not report completion when Babel cannot transform a file', async () => {
14
+ const projectDir = await mkdtemp(join(tmpdir(), 'tungsten-compile-test-'));
15
+ const cliLocation = join(findProjectDir(import.meta.url), 'dist', 'bin', 'index.js');
16
+ try {
17
+ await writeFile(join(projectDir, 'package.json'), '{"type":"module"}');
18
+ await writeFile(join(projectDir, 'broken.jsx'), 'export const broken = <div>');
19
+ let error;
20
+ try {
21
+ await execFileAsync(process.execPath, [cliLocation, 'compile', '--js', '--quiet'], {
22
+ cwd: projectDir
23
+ });
24
+ } catch (caught) {
25
+ error = caught;
26
+ }
27
+ expect(error).not.to.equal(undefined);
28
+ expect(error?.code).not.to.equal(0);
29
+ expect(error?.stdout ?? '').not.to.contain('Compile complete');
30
+ } finally {
31
+ await rm(projectDir, {
32
+ recursive: true,
33
+ force: true
34
+ });
35
+ }
36
+ });
37
+ it('writes all JavaScript and readiness output beneath the selected locations', async () => {
38
+ const projectDir = await mkdtemp(join(tmpdir(), 'tungsten-compile-output-test-'));
39
+ const cliLocation = join(findProjectDir(import.meta.url), 'dist', 'bin', 'index.js');
40
+ try {
41
+ await writeFile(join(projectDir, 'package.json'), '{"type":"module"}');
42
+ await writeFile(join(projectDir, 'entry.jsx'), 'export const element = <div />');
43
+ const {
44
+ stdout
45
+ } = await execFileAsync(process.execPath, [cliLocation, 'compile', '--js', '--output', '.tungsten/test', '--ready-file', '.tungsten/test.ready', '--quiet'], {
46
+ cwd: projectDir
47
+ });
48
+ const compiled = await readFile(join(projectDir, '.tungsten/test/code/entry.js'), 'utf8');
49
+ const ready = JSON.parse(await readFile(join(projectDir, '.tungsten/test.ready'), 'utf8'));
50
+ expect(stdout).to.contain('Compile complete');
51
+ expect(compiled).to.contain('export const element');
52
+ expect(ready.ready).to.equal(true);
53
+ expect(ready.output).to.equal(join(projectDir, '.tungsten/test'));
54
+ } finally {
55
+ await rm(projectDir, {
56
+ recursive: true,
57
+ force: true
58
+ });
59
+ }
60
+ });
61
+ });
@@ -6,7 +6,17 @@ type CompileJavascriptResult = {
6
6
  watcher: chokidar.FSWatcher | null;
7
7
  copyWatcher: chokidar.FSWatcher | null;
8
8
  importAliases: ImportAliases;
9
+ initialSuccess: boolean;
9
10
  };
10
- export declare function compileJavascript(projectDir: string, appConfig: FrameworkConfigComplete, codeLocation: string, sourceLocation: string, styleImportBase: string, buildLocation: string, buildCodeLocation: string, mode: Mode, watch?: boolean): Promise<CompileJavascriptResult>;
11
+ export type JavascriptCompilationCycle = {
12
+ success: boolean;
13
+ file?: string;
14
+ };
15
+ export type CompileJavascriptOptions = {
16
+ quiet?: boolean;
17
+ packagesCacheLocation?: string;
18
+ onCycleComplete?: ((cycle: JavascriptCompilationCycle) => void | Promise<void>) | undefined;
19
+ };
20
+ export declare function compileJavascript(projectDir: string, appConfig: FrameworkConfigComplete, codeLocation: string, sourceLocation: string, styleImportBase: string, buildLocation: string, buildCodeLocation: string, mode: Mode, watch?: boolean, options?: CompileJavascriptOptions): Promise<CompileJavascriptResult>;
11
21
  export {};
12
22
  //# sourceMappingURL=compileJavascript.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"compileJavascript.d.ts","sourceRoot":"","sources":["../../src/build/compileJavascript.ts"],"names":[],"mappings":"AAEA,OAAO,QAAQ,MAAM,UAAU,CAAA;AAO/B,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAA;AACpE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AACvD,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAA;AAetC,KAAK,uBAAuB,GAAG;IAC3B,OAAO,EAAE,QAAQ,CAAC,SAAS,GAAG,IAAI,CAAA;IAClC,WAAW,EAAE,QAAQ,CAAC,SAAS,GAAG,IAAI,CAAA;IACtC,aAAa,EAAE,aAAa,CAAA;CAC/B,CAAA;AAKD,wBAAsB,iBAAiB,CACnC,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,uBAAuB,EACtD,YAAY,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,EACrE,aAAa,EAAE,MAAM,EAAE,iBAAiB,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,UAAO,GAC3E,OAAO,CAAC,uBAAuB,CAAC,CAwPlC"}
1
+ {"version":3,"file":"compileJavascript.d.ts","sourceRoot":"","sources":["../../src/build/compileJavascript.ts"],"names":[],"mappings":"AAEA,OAAO,QAAQ,MAAM,UAAU,CAAA;AAO/B,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAA;AACpE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AACvD,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAA;AAetC,KAAK,uBAAuB,GAAG;IAC3B,OAAO,EAAE,QAAQ,CAAC,SAAS,GAAG,IAAI,CAAA;IAClC,WAAW,EAAE,QAAQ,CAAC,SAAS,GAAG,IAAI,CAAA;IACtC,aAAa,EAAE,aAAa,CAAA;IAC5B,cAAc,EAAE,OAAO,CAAA;CAC1B,CAAA;AAED,MAAM,MAAM,0BAA0B,GAAG;IACrC,OAAO,EAAE,OAAO,CAAA;IAChB,IAAI,CAAC,EAAE,MAAM,CAAA;CAChB,CAAA;AAED,MAAM,MAAM,wBAAwB,GAAG;IACnC,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,qBAAqB,CAAC,EAAE,MAAM,CAAA;IAC9B,eAAe,CAAC,EAAE,CAAC,CAAC,KAAK,EAAE,0BAA0B,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,GAAG,SAAS,CAAA;CAC9F,CAAA;AAKD,wBAAsB,iBAAiB,CACnC,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,uBAAuB,EACtD,YAAY,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,EACrE,aAAa,EAAE,MAAM,EAAE,iBAAiB,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,UAAO,EAC1E,OAAO,GAAE,wBAA6B,GACvC,OAAO,CAAC,uBAAuB,CAAC,CAwSlC"}
@@ -13,7 +13,7 @@ import { TungstenError } from "../TungstenError.js";
13
13
  import { getFrameworkDir } from "../getFrameworkDir.js";
14
14
  ///// needs work to work in prod mode
15
15
  ///// see babel config
16
- export async function compileJavascript(projectDir, appConfig, codeLocation, sourceLocation, styleImportBase, buildLocation, buildCodeLocation, mode, watch = true) {
16
+ export async function compileJavascript(projectDir, appConfig, codeLocation, sourceLocation, styleImportBase, buildLocation, buildCodeLocation, mode, watch = true, options = {}) {
17
17
  cliOut(`Compiling app code`);
18
18
  let dependencyGraphDir = '';
19
19
  let dependencyGraphLocation = '';
@@ -23,13 +23,13 @@ export async function compileJavascript(projectDir, appConfig, codeLocation, sou
23
23
  let promises = [];
24
24
  let config;
25
25
  if (mode === 'dev') {
26
- dependencyGraphDir = join(projectDir, packagesCacheFolder);
26
+ dependencyGraphDir = options.packagesCacheLocation ?? join(projectDir, packagesCacheFolder);
27
27
  dependencyGraphLocation = join(dependencyGraphDir, '.dependency-graph.js');
28
28
  oldDependencyGraph = {};
29
29
  dependencyGraph = {};
30
30
  importAliases = {};
31
31
  promises = [];
32
- config = makeBabelUserDevConfig(projectDir, codeLocation, sourceLocation, styleImportBase, buildLocation, buildCodeLocation, oldDependencyGraph, dependencyGraph, importAliases, promises);
32
+ config = makeBabelUserDevConfig(projectDir, codeLocation, sourceLocation, styleImportBase, buildLocation, buildCodeLocation, dependencyGraphDir, oldDependencyGraph, dependencyGraph, importAliases, promises);
33
33
  } else {
34
34
  config = makeBabelUserProdConfig(projectDir, codeLocation, sourceLocation, styleImportBase);
35
35
  }
@@ -37,8 +37,9 @@ export async function compileJavascript(projectDir, appConfig, codeLocation, sou
37
37
  // compile with the API
38
38
  const codeLocationLength = codeLocation.length + 1;
39
39
  const transformPromises = [];
40
+ const failedFiles = new Set();
40
41
  async function transformFile(file) {
41
- console.log('transforming file', file);
42
+ if (!options.quiet) console.log('transforming file', file);
42
43
  try {
43
44
  let rel = file.slice(codeLocationLength);
44
45
  if (rel.endsWith('.jsx')) rel = rel.slice(0, -1);
@@ -57,11 +58,25 @@ export async function compileJavascript(projectDir, appConfig, codeLocation, sou
57
58
  //// Using the sync version here, because the promise version keeps bugging out - node bug?
58
59
  //await fsPromises.writeFile(dest, code)
59
60
  fs.writeFileSync(dest, code);
61
+ failedFiles.delete(file);
60
62
  } catch (e) {
63
+ failedFiles.add(file);
61
64
  cliError(`Tungsten: Error transforming project file ${file}`);
62
65
  cliLog(e);
63
- //throw new TungstenError(`compileJavascript() error: error when compiling application file ${e}`)
66
+ throw e;
67
+ }
68
+ }
69
+ async function deleteTransformedFile(file) {
70
+ let rel = file.slice(codeLocationLength);
71
+ if (rel.endsWith('.jsx')) rel = rel.slice(0, -1);
72
+ const dest = join(buildCodeLocation, rel);
73
+ try {
74
+ await fsPromises.unlink(dest);
75
+ } catch (error) {
76
+ const fileError = error;
77
+ if (fileError.code !== 'ENOENT') throw error;
64
78
  }
79
+ failedFiles.delete(file);
65
80
  }
66
81
  async function copyFile(file) {
67
82
  try {
@@ -94,6 +109,7 @@ export async function compileJavascript(projectDir, appConfig, codeLocation, sou
94
109
  // get a list of files
95
110
  const watchGlob = slash(`${codeLocation}/**/*.js{,x}`);
96
111
  const ignored = [];
112
+ ignored.push(slash(`${buildLocation}/**`));
97
113
  if (appConfig.ignoreDirs) {
98
114
  ignored.push(...appConfig.ignoreDirs.map(folder => slash(`${codeLocation}/${folder}/**`)));
99
115
  }
@@ -118,21 +134,38 @@ export async function compileJavascript(projectDir, appConfig, codeLocation, sou
118
134
  paths.forEach(file => {
119
135
  transformPromises.push(transformFile(file));
120
136
  });
121
- await Promise.all(transformPromises);
137
+ const transformResults = await Promise.allSettled(transformPromises);
138
+ const transformFailures = transformResults.filter(result => result.status === 'rejected').map(result => result.reason);
139
+ let deferredWorkPosition = 0;
140
+ const settleDeferredWork = async () => {
141
+ const currentPromises = promises.slice(deferredWorkPosition);
142
+ deferredWorkPosition = promises.length;
143
+ const deferredResults = await Promise.allSettled(currentPromises);
144
+ return deferredResults.filter(result => result.status === 'rejected').map(result => result.reason);
145
+ };
146
+ const initialFailures = [...transformFailures, ...(await settleDeferredWork())];
147
+ const initialSuccess = initialFailures.length === 0 && failedFiles.size === 0;
148
+ function writeDependencyGraph() {
149
+ if (mode !== 'dev') return;
150
+ if (!fs.existsSync(dependencyGraphDir)) {
151
+ fs.mkdirSync(dependencyGraphDir, {
152
+ recursive: true
153
+ });
154
+ }
155
+ fs.writeFileSync(dependencyGraphLocation, `export const graph = ${serializeJavascript(dependencyGraph)}`);
156
+ }
122
157
  if (!watch) {
158
+ if (!initialSuccess) {
159
+ throw new AggregateError(initialFailures, 'One or more JavaScript files could not be compiled');
160
+ }
123
161
  if (mode === 'dev') {
124
- await Promise.all(promises);
125
- if (!fs.existsSync(dependencyGraphDir)) {
126
- fs.mkdirSync(dependencyGraphDir, {
127
- recursive: true
128
- });
129
- }
130
- fs.writeFileSync(dependencyGraphLocation, `export const graph = ${serializeJavascript(dependencyGraph)}`);
162
+ writeDependencyGraph();
131
163
  }
132
164
  return {
133
165
  watcher: null,
134
166
  copyWatcher: null,
135
- importAliases
167
+ importAliases,
168
+ initialSuccess
136
169
  };
137
170
  }
138
171
  const watcher = chokidar.watch(watchGlob, {
@@ -140,13 +173,32 @@ export async function compileJavascript(projectDir, appConfig, codeLocation, sou
140
173
  ignoreInitial: true
141
174
  //useFsEvents: false
142
175
  });
143
- watcher.on('all', async (event, file) => {
176
+ let watchCycle = Promise.resolve();
177
+ watcher.on('all', (event, file) => {
144
178
  file = slash(file);
145
- if (event === 'add') {
146
- transformFile(file);
147
- }
148
- if (event === 'change') {
149
- transformFile(file);
179
+ if (event === 'add' || event === 'change' || event === 'unlink') {
180
+ watchCycle = watchCycle.then(async () => {
181
+ let success = false;
182
+ try {
183
+ if (event === 'unlink') {
184
+ await deleteTransformedFile(file);
185
+ } else {
186
+ await transformFile(file);
187
+ }
188
+ const failures = await settleDeferredWork();
189
+ success = failures.length === 0 && failedFiles.size === 0;
190
+ if (success) writeDependencyGraph();
191
+ } catch {
192
+ success = false;
193
+ }
194
+ await options.onCycleComplete?.({
195
+ success,
196
+ file
197
+ });
198
+ }).catch(error => {
199
+ cliError('Tungsten: Error completing JavaScript watch cycle');
200
+ cliLog(error);
201
+ });
150
202
  }
151
203
  });
152
204
  let copyWatcher = null;
@@ -172,21 +224,14 @@ export async function compileJavascript(projectDir, appConfig, codeLocation, sou
172
224
  if (copyWatcher) awaiting.set(copyWatcher, true);
173
225
  watcher.on('ready', async () => {
174
226
  //cliNews('App Built')
175
- if (mode === 'dev') {
176
- await Promise.all(promises);
177
- if (!fs.existsSync(dependencyGraphDir)) {
178
- fs.mkdirSync(dependencyGraphDir, {
179
- recursive: true
180
- });
181
- }
182
- fs.writeFileSync(dependencyGraphLocation, `export const graph = ${serializeJavascript(dependencyGraph)}`);
183
- }
227
+ if (initialSuccess) writeDependencyGraph();
184
228
  awaiting.delete(watcher);
185
229
  if (awaiting.size === 0) {
186
230
  resolve({
187
231
  watcher,
188
232
  copyWatcher,
189
- importAliases
233
+ importAliases,
234
+ initialSuccess
190
235
  });
191
236
  }
192
237
  });
@@ -198,7 +243,8 @@ export async function compileJavascript(projectDir, appConfig, codeLocation, sou
198
243
  resolve({
199
244
  watcher,
200
245
  copyWatcher,
201
- importAliases
246
+ importAliases,
247
+ initialSuccess
202
248
  });
203
249
  }
204
250
  });
@@ -1,4 +1,4 @@
1
1
  import type { Mode } from '../Mode.js';
2
2
  import { FrameworkConfigComplete } from '../FrameworkConfig.js';
3
- export declare function createClientFiles(config: FrameworkConfigComplete, mode: Mode): Promise<void>;
3
+ export declare function createClientFiles(config: FrameworkConfigComplete, mode: Mode, buildLocation?: string): Promise<void>;
4
4
  //# sourceMappingURL=createClientFiles.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"createClientFiles.d.ts","sourceRoot":"","sources":["../../src/build/createClientFiles.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAA;AAOtC,OAAO,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAA;AAG/D,wBAAsB,iBAAiB,CAAC,MAAM,EAAE,uBAAuB,EAAE,IAAI,EAAE,IAAI,iBA8ElF"}
1
+ {"version":3,"file":"createClientFiles.d.ts","sourceRoot":"","sources":["../../src/build/createClientFiles.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAA;AAOtC,OAAO,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAA;AAG/D,wBAAsB,iBAAiB,CACnC,MAAM,EAAE,uBAAuB,EAC/B,IAAI,EAAE,IAAI,EACV,aAAa,CAAC,EAAE,MAAM,iBAgFzB"}
@@ -3,9 +3,9 @@ import { join } from 'path';
3
3
  import { buildCodeSubPath, devBuildOuterFolder, prodBuildFolder, clientFolder, frameworkDistFolder, frameworkClientFolder } from "../settings.js";
4
4
  import { fixExtension } from "../fixExtension.js";
5
5
  import { findProjectDir } from "../findProjectDir.js";
6
- export async function createClientFiles(config, mode) {
6
+ export async function createClientFiles(config, mode, buildLocation) {
7
7
  //console.log('creating entry file')
8
- const specificBuildFolder = mode === 'dev' ? devBuildOuterFolder : prodBuildFolder;
8
+ const specificBuildFolder = buildLocation ?? join(process.cwd(), mode === 'dev' ? devBuildOuterFolder : prodBuildFolder);
9
9
  const codeSubPath = `${buildCodeSubPath}/`;
10
10
  const frameworkDir = findProjectDir(import.meta.url);
11
11
  const routesLocation = config.routesLocation;
@@ -13,20 +13,20 @@ export async function createClientFiles(config, mode) {
13
13
  const [routeFilePath, routesExportName] = routesLocation;
14
14
  const promises = [
15
15
  // ensure the folder exists
16
- fsPromises.mkdir(join(process.cwd(), specificBuildFolder, `${clientFolder}`), {
16
+ fsPromises.mkdir(join(specificBuildFolder, `${clientFolder}`), {
17
17
  recursive: true
18
18
  }),
19
19
  // client.js file
20
20
  fsPromises.copyFile(join(frameworkDir, frameworkDistFolder, frameworkClientFolder, 'client.js'),
21
21
  // from
22
- join(process.cwd(), specificBuildFolder, `${clientFolder}/client.js`)),
22
+ join(specificBuildFolder, `${clientFolder}/client.js`)),
23
23
  // cjsHelpers.js file
24
24
  fsPromises.copyFile(join(frameworkDir, frameworkDistFolder, frameworkClientFolder, 'cjsHelpers.js'),
25
25
  // from
26
- join(process.cwd(), specificBuildFolder, `${clientFolder}/cjsHelpers.js`)),
26
+ join(specificBuildFolder, `${clientFolder}/cjsHelpers.js`)),
27
27
  // app routes stuff
28
- fsPromises.writeFile(join(process.cwd(), specificBuildFolder, clientFolder, 'routes.js'), `export { ${routesExportName} as routes } from '../${codeSubPath}${fixExtension(routeFilePath)}'`)];
29
- const clientRootComponentFileLocation = join(process.cwd(), specificBuildFolder, clientFolder, 'RootComponent.js');
28
+ fsPromises.writeFile(join(specificBuildFolder, clientFolder, 'routes.js'), `export { ${routesExportName} as routes } from '../${codeSubPath}${fixExtension(routeFilePath)}'`)];
29
+ const clientRootComponentFileLocation = join(specificBuildFolder, clientFolder, 'RootComponent.js');
30
30
  if (config.useRootComponent) {
31
31
  const rootComponentRelFilePath = config.rootComponent;
32
32
  const rcFile = rootComponentRelFilePath.split('/').pop();
@@ -1,4 +1,4 @@
1
1
  import type { Mode } from '../Mode.js';
2
2
  import { FrameworkConfigComplete } from '../FrameworkConfig.js';
3
- export declare function createInstanceConfigFile(config: FrameworkConfigComplete, mode: Mode): Promise<void>;
3
+ export declare function createInstanceConfigFile(config: FrameworkConfigComplete, mode: Mode, buildLocation?: string): Promise<void>;
4
4
  //# sourceMappingURL=createInstanceConfigFile.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"createInstanceConfigFile.d.ts","sourceRoot":"","sources":["../../src/build/createInstanceConfigFile.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAA;AAEtC,OAAO,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAA;AAI/D,wBAAsB,wBAAwB,CAAC,MAAM,EAAE,uBAAuB,EAAE,IAAI,EAAE,IAAI,iBA2BzF"}
1
+ {"version":3,"file":"createInstanceConfigFile.d.ts","sourceRoot":"","sources":["../../src/build/createInstanceConfigFile.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAA;AAEtC,OAAO,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAA;AAI/D,wBAAsB,wBAAwB,CAC1C,MAAM,EAAE,uBAAuB,EAC/B,IAAI,EAAE,IAAI,EACV,aAAa,CAAC,EAAE,MAAM,iBA6BzB"}
@@ -2,10 +2,10 @@ import { promises as fsPromises } from 'fs';
2
2
  import { join, dirname } from 'path';
3
3
  import { devBuildOuterFolder, prodBuildFolder } from "../settings.js";
4
4
  import { TungstenError } from "../TungstenError.js";
5
- export async function createInstanceConfigFile(config, mode) {
5
+ export async function createInstanceConfigFile(config, mode, buildLocation) {
6
6
  //console.log('creating app config')
7
- const specificBuildFolder = mode === 'dev' ? devBuildOuterFolder : prodBuildFolder;
8
- const appConfigLocation = join(process.cwd(), specificBuildFolder, '.tungsten.config.js');
7
+ const specificBuildFolder = buildLocation ?? join(process.cwd(), mode === 'dev' ? devBuildOuterFolder : prodBuildFolder);
8
+ const appConfigLocation = join(specificBuildFolder, '.tungsten.config.js');
9
9
  // // ensure the folder exists
10
10
  // await fsPromises.mkdir(
11
11
  // join(process.cwd(), specificBuildFolder),
@@ -1,5 +1,5 @@
1
1
  import type { TransformOptions } from '@babel/core';
2
2
  import type { ImportAliases } from './ImportAliases.js';
3
3
  import { DependencyGraph } from '../babelPlugins/BabelTransformPackageImports.js';
4
- export declare function makeBabelUserDevConfig(projectDir: string, absCodeDir: string, absSourceDir: string, absStyleImportBase: string, buildLocation: string, buildCodeLocation: string, oldDependencyGraph: DependencyGraph, dependencyGraph: DependencyGraph, importAliases: ImportAliases, promises: Promise<any>[]): TransformOptions;
4
+ export declare function makeBabelUserDevConfig(projectDir: string, absCodeDir: string, absSourceDir: string, absStyleImportBase: string, buildLocation: string, buildCodeLocation: string, packagesCacheLocation: string, oldDependencyGraph: DependencyGraph, dependencyGraph: DependencyGraph, importAliases: ImportAliases, promises: Promise<any>[]): TransformOptions;
5
5
  //# sourceMappingURL=makeBabelUserDevConfig.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"makeBabelUserDevConfig.d.ts","sourceRoot":"","sources":["../../src/build/makeBabelUserDevConfig.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAA;AAKnD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AAEvD,OAAO,EAAoC,eAAe,EAAE,MAAM,iDAAiD,CAAA;AAMnH,wBAAgB,sBAAsB,CAClC,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,MAAM,EAClB,YAAY,EAAE,MAAM,EACpB,kBAAkB,EAAE,MAAM,EAC1B,aAAa,EAAE,MAAM,EACrB,iBAAiB,EAAE,MAAM,EACzB,kBAAkB,EAAE,eAAe,EACnC,eAAe,EAAE,eAAe,EAChC,aAAa,EAAE,aAAa,EAC5B,QAAQ,EAAE,OAAO,CAAC,GAAG,CAAC,EAAE,GACzB,gBAAgB,CA0BlB"}
1
+ {"version":3,"file":"makeBabelUserDevConfig.d.ts","sourceRoot":"","sources":["../../src/build/makeBabelUserDevConfig.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAA;AAKnD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AAEvD,OAAO,EAAoC,eAAe,EAAE,MAAM,iDAAiD,CAAA;AAMnH,wBAAgB,sBAAsB,CAClC,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,MAAM,EAClB,YAAY,EAAE,MAAM,EACpB,kBAAkB,EAAE,MAAM,EAC1B,aAAa,EAAE,MAAM,EACrB,iBAAiB,EAAE,MAAM,EACzB,qBAAqB,EAAE,MAAM,EAC7B,kBAAkB,EAAE,eAAe,EACnC,eAAe,EAAE,eAAe,EAChC,aAAa,EAAE,aAAa,EAC5B,QAAQ,EAAE,OAAO,CAAC,GAAG,CAAC,EAAE,GACzB,gBAAgB,CA2BlB"}
@@ -6,13 +6,14 @@ import { MakeBabelTransformPackageImports } from "../babelPlugins/BabelTransform
6
6
  import { componentCssFolder, componentCssFile } from "../settings.js";
7
7
  import userCommonConfig from "./babel.user.common.config.js";
8
8
  import { MakeBabelTransformCssImports } from "../babelPlugins/BabelTransformCssImports.js";
9
- export function makeBabelUserDevConfig(projectDir, absCodeDir, absSourceDir, absStyleImportBase, buildLocation, buildCodeLocation, oldDependencyGraph, dependencyGraph, importAliases, promises) {
9
+ export function makeBabelUserDevConfig(projectDir, absCodeDir, absSourceDir, absStyleImportBase, buildLocation, buildCodeLocation, packagesCacheLocation, oldDependencyGraph, dependencyGraph, importAliases, promises) {
10
10
  const userDevConfig = objectCopy(userCommonConfig);
11
11
  userDevConfig.plugins.push(MakeBabelTransformPackageImports({
12
12
  projectDir: projectDir,
13
13
  codeDir: absCodeDir,
14
14
  buildLocation,
15
15
  buildCodeLocation,
16
+ packagesCacheLocation,
16
17
  oldDependencyGraph,
17
18
  dependencyGraph,
18
19
  importAliases,
@@ -53,8 +53,11 @@ describe('parseSelectorsRich()', ({
53
53
  const input2 = 'html body';
54
54
  it(`parses out two tag selectors from '${input2}'`, () => {
55
55
  const selectors = parseSelectorsRich(input2);
56
- console.log('selectors', selectors);
57
- console.log('expected', [tagSelector('html'), tagSelector('body')]);
56
+ // console.log('selectors', selectors)
57
+ // console.log('expected', [
58
+ // tagSelector('html'),
59
+ // tagSelector('body')
60
+ // ])
58
61
  selectors.should.deep.equal([tagSelector('html'), whitespace(), tagSelector('body')]);
59
62
  });
60
63
  const input3 = '.foo';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tungsten",
3
- "version": "0.2.6",
3
+ "version": "0.2.7",
4
4
  "description": "",
5
5
  "type": "module",
6
6
  "bin": {
package/readme.md CHANGED
@@ -16,6 +16,17 @@ transforms), stylesheets, client support files, assets, and public files into
16
16
  Each selected target's existing generated output is cleaned before the initial
17
17
  compilation, including when watch mode is used. Pass `--no-clean` to preserve
18
18
  existing output.
19
+
20
+ Use `--output` to select an independent output root. The layout below that root
21
+ is the same as `.tungsten/dev`, including `code`, `.client`, `.static`,
22
+ `.assets`, `.public`, `.componentCss`, and `.packages`:
23
+
24
+ ```sh
25
+ tungsten compile --output .tungsten/test
26
+ tungsten compile --output .tungsten/test --watch
27
+ ```
28
+
29
+ Cleaning and generated package-cache data are scoped to the selected output.
19
30
  Limit the work with one or more options:
20
31
 
21
32
  ```sh
@@ -27,7 +38,7 @@ tungsten compile --public
27
38
  tungsten compile --js --css
28
39
  ```
29
40
 
30
- `--all` explicitly selects all three targets.
41
+ `--all` explicitly selects all five targets.
31
42
 
32
43
  Add `--watch` to keep the JavaScript, stylesheet, asset, and/or public-file
33
44
  compiler running after the initial pass. Client support files are still
@@ -37,3 +48,13 @@ generated once:
37
48
  tungsten compile --watch
38
49
  tungsten compile --js --watch
39
50
  ```
51
+
52
+ For process orchestration, `--ready-file <file>` writes a small JSON file only
53
+ after the initial compilation succeeds. A failed JavaScript watch cycle removes
54
+ the file, and a later successful cycle recreates it. `--quiet` suppresses
55
+ per-file transformation messages while retaining errors and cycle status:
56
+
57
+ ```sh
58
+ tungsten compile --watch --output .tungsten/test \
59
+ --ready-file .tungsten/test.ready --quiet
60
+ ```