tungsten 0.2.5 → 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.
Files changed (40) hide show
  1. package/dist/babelPlugins/BabelTransformPackageImports.d.ts +1 -0
  2. package/dist/babelPlugins/BabelTransformPackageImports.d.ts.map +1 -1
  3. package/dist/babelPlugins/BabelTransformPackageImports.js +2 -2
  4. package/dist/bin/commands/compile.d.ts +2 -0
  5. package/dist/bin/commands/compile.d.ts.map +1 -0
  6. package/dist/bin/commands/compile.js +165 -0
  7. package/dist/bin/commands/compile.sxyt.d.ts +2 -0
  8. package/dist/bin/commands/compile.sxyt.d.ts.map +1 -0
  9. package/dist/bin/commands/compile.sxyt.js +61 -0
  10. package/dist/bin/index.d.ts.map +1 -1
  11. package/dist/bin/index.js +6 -0
  12. package/dist/build/babel.user.common.config.d.ts.map +1 -1
  13. package/dist/build/babel.user.common.config.js +2 -0
  14. package/dist/build/compileJavascript.d.ts +12 -2
  15. package/dist/build/compileJavascript.d.ts.map +1 -1
  16. package/dist/build/compileJavascript.js +93 -30
  17. package/dist/build/compileStyles.d.ts +1 -1
  18. package/dist/build/compileStyles.d.ts.map +1 -1
  19. package/dist/build/compileStyles.js +7 -1
  20. package/dist/build/copyAssets.d.ts +1 -1
  21. package/dist/build/copyAssets.d.ts.map +1 -1
  22. package/dist/build/copyAssets.js +7 -1
  23. package/dist/build/copyPublicFiles.d.ts +1 -1
  24. package/dist/build/copyPublicFiles.d.ts.map +1 -1
  25. package/dist/build/copyPublicFiles.js +7 -1
  26. package/dist/build/createClientFiles.d.ts +1 -1
  27. package/dist/build/createClientFiles.d.ts.map +1 -1
  28. package/dist/build/createClientFiles.js +7 -7
  29. package/dist/build/createInstanceConfigFile.d.ts +1 -1
  30. package/dist/build/createInstanceConfigFile.d.ts.map +1 -1
  31. package/dist/build/createInstanceConfigFile.js +3 -3
  32. package/dist/build/makeBabelUserDevConfig.d.ts +1 -1
  33. package/dist/build/makeBabelUserDevConfig.d.ts.map +1 -1
  34. package/dist/build/makeBabelUserDevConfig.js +2 -1
  35. package/dist/hydrate/hydrate.js +1 -16
  36. package/dist/postcssPlugins/parseSelectorsRich.sxyt.js +5 -2
  37. package/dist/update/integrateUpdateVdom.d.ts.map +1 -1
  38. package/dist/update/integrateUpdateVdom.js +6 -40
  39. package/package.json +1 -1
  40. package/readme.md +58 -1
@@ -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":"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"}
@@ -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) {
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=compile.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compile.d.ts","sourceRoot":"","sources":["../../../src/bin/commands/compile.ts"],"names":[],"mappings":"AAyPA,OAAO,EAAE,CAAA"}
@@ -0,0 +1,165 @@
1
+ import { dirname, join, resolve } from 'path';
2
+ import { promises as fsPromises } from 'fs';
3
+ import rmfr from 'rmfr';
4
+ import { compileJavascript } from "../../build/compileJavascript.js";
5
+ import { compileStyles } from "../../build/compileStyles.js";
6
+ import { copyAssets } from "../../build/copyAssets.js";
7
+ import { copyPublicFiles } from "../../build/copyPublicFiles.js";
8
+ import { createClientFiles } from "../../build/createClientFiles.js";
9
+ import { createInstanceConfigFile } from "../../build/createInstanceConfigFile.js";
10
+ import { getUserConfig } from "../../getUserConfig.js";
11
+ import { buildCodeSubPath, assetsFolder, clientFolder, componentCssFolder, devBuildOuterFolder, packagesCacheFolder, packagesFolder, publicFolder, staticFolder } from "../../settings.js";
12
+ import { cliError, cliNews, cliOut } from "../../cliOutput.js";
13
+ const targetOptions = {
14
+ '--js': 'js',
15
+ '--css': 'css',
16
+ '--client': 'client',
17
+ '--assets': 'assets',
18
+ '--public': 'public'
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
+ }
31
+ if (args.includes('--help') || args.includes('-h')) {
32
+ cliOut('Usage: tungsten compile [targets] [--all] [--watch] [--no-clean] [--output <dir>]');
33
+ cliOut('Targets: --js, --css, --client, --assets, --public');
34
+ cliOut('With no target options, all targets are compiled.');
35
+ cliOut('Options: --output <dir>, --ready-file <file>, --quiet');
36
+ process.exit(0);
37
+ }
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));
46
+ if (unknownOptions.length > 0) {
47
+ cliError(`Unknown compile option${unknownOptions.length === 1 ? '' : 's'}: ${unknownOptions.join(', ')}`);
48
+ cliOut('Usage: tungsten compile [targets] [--all] [--watch] [--no-clean] [--output <dir>]');
49
+ process.exit(1);
50
+ }
51
+ const outputOption = optionValue('--output');
52
+ const readyFileOption = optionValue('--ready-file');
53
+ const requestedTargets = new Set();
54
+ for (const arg of args) {
55
+ const target = targetOptions[arg];
56
+ if (target !== undefined) requestedTargets.add(target);
57
+ }
58
+ const targets = requestedTargets.size === 0 || args.includes('--all') ? new Set(['js', 'css', 'client', 'assets', 'public']) : requestedTargets;
59
+ const watch = args.includes('--watch');
60
+ const clean = !args.includes('--no-clean');
61
+ const quiet = args.includes('--quiet');
62
+ const projectDir = process.cwd();
63
+ const config = await getUserConfig();
64
+ const codeLocation = join(projectDir, config.codeDir);
65
+ const relSourceDir = config.sourceDir !== undefined && config.sourceDir !== '' ? config.sourceDir : config.codeDir;
66
+ const sourceLocation = join(projectDir, relSourceDir);
67
+ const styleImportBase = config.styleImportBase !== undefined ? join(sourceLocation, config.styleImportBase) : sourceLocation;
68
+ const buildLocation = outputOption !== undefined ? resolve(projectDir, outputOption) : join(projectDir, devBuildOuterFolder);
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();
95
+ const cleanTasks = [];
96
+ if (clean && targets.has('js')) {
97
+ cleanTasks.push(rmfr(buildCodeLocation), rmfr(join(buildLocation, componentCssFolder)), rmfr(join(buildLocation, packagesFolder)), rmfr(packagesCacheLocation));
98
+ }
99
+ if (clean && targets.has('css')) {
100
+ cleanTasks.push(rmfr(join(buildLocation, staticFolder)));
101
+ }
102
+ if (clean && targets.has('client')) {
103
+ cleanTasks.push(rmfr(join(buildLocation, clientFolder)), rmfr(join(buildLocation, '.tungsten.config.js')));
104
+ }
105
+ if (clean) {
106
+ if (targets.has('assets')) cleanTasks.push(rmfr(join(buildLocation, assetsFolder)));
107
+ if (targets.has('public')) cleanTasks.push(rmfr(join(buildLocation, publicFolder)));
108
+ cliOut(`Cleaning compile output: ${[...targets].join(', ')}`);
109
+ await Promise.all(cleanTasks);
110
+ }
111
+ const compilationTasks = [];
112
+ let javascriptInitialSuccess = true;
113
+ if (targets.has('js')) {
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
+ }));
131
+ }
132
+ if (targets.has('css')) {
133
+ compilationTasks.push(compileStyles(projectDir, config, styleImportBase, buildLocation, watch));
134
+ }
135
+ if (targets.has('client')) {
136
+ compilationTasks.push(createInstanceConfigFile(config, 'dev', buildLocation));
137
+ compilationTasks.push(createClientFiles(config, 'dev', buildLocation));
138
+ }
139
+ if (targets.has('assets')) {
140
+ const assetsTask = copyAssets(projectDir, config, buildLocation, watch);
141
+ if (assetsTask !== undefined) compilationTasks.push(assetsTask);
142
+ }
143
+ if (targets.has('public')) {
144
+ compilationTasks.push(copyPublicFiles(projectDir, config, buildLocation, watch));
145
+ }
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
+ }
159
+ if (watch && (targets.has('js') || targets.has('css') || targets.has('assets') || targets.has('public'))) {
160
+ cliNews(initialSuccess ? 'Watching for changes' : 'Watching for changes; waiting for a successful cycle');
161
+ } else {
162
+ // The underlying development compilers watch after their initial pass.
163
+ // End them when this command is being used for one-shot test preparation.
164
+ process.exit(0);
165
+ }
@@ -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
+ });
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/bin/index.ts"],"names":[],"mappings":"AA8CA,OAAO,EAAE,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/bin/index.ts"],"names":[],"mappings":"AAmDA,OAAO,EAAE,CAAA"}
package/dist/bin/index.js CHANGED
@@ -34,6 +34,12 @@ switch (command) {
34
34
  await import("./commands/clean.js");
35
35
  break;
36
36
  }
37
+ case 'compile':
38
+ {
39
+ process.env.__TUNGSTEN_ENV = 'development';
40
+ await import("./commands/compile.js");
41
+ break;
42
+ }
37
43
  case 'compile-simple-package':
38
44
  {
39
45
  await import("./commands/compileSimplePackage.js");
@@ -1 +1 @@
1
- {"version":3,"file":"babel.user.common.config.d.ts","sourceRoot":"","sources":["../../src/build/babel.user.common.config.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAA;AAcnD,QAAA,MAAM,gBAAgB,EAAE,gBA2BvB,CAAA;AAED,eAAe,gBAAgB,CAAA"}
1
+ {"version":3,"file":"babel.user.common.config.d.ts","sourceRoot":"","sources":["../../src/build/babel.user.common.config.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAA;AAcnD,QAAA,MAAM,gBAAgB,EAAE,gBA6BvB,CAAA;AAED,eAAe,gBAAgB,CAAA"}
@@ -20,6 +20,8 @@ const userCommonConfig = {
20
20
  // }],
21
21
  ],
22
22
  plugins: [[babelPluginSxyModuleResolve, {
23
+ // This alias is resolved after Tungsten rewrites package imports.
24
+ "loglevel": "silent",
23
25
  "alias": {
24
26
  "tungsten/jsx-runtime": "tungsten/jsxRuntime.js" // fix the import location created by @babel/preset-react
25
27
  }
@@ -3,10 +3,20 @@ import type { FrameworkConfigComplete } from '../FrameworkConfig.js';
3
3
  import type { ImportAliases } from './ImportAliases.js';
4
4
  import type { Mode } from '../Mode.js';
5
5
  type CompileJavascriptResult = {
6
- watcher: chokidar.FSWatcher;
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): 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,CAAA;IAC3B,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,GAC7D,OAAO,CAAC,uBAAuB,CAAC,CAmOlC"}
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,23 +13,23 @@ 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) {
16
+ export async function compileJavascript(projectDir, appConfig, codeLocation, sourceLocation, styleImportBase, buildLocation, buildCodeLocation, mode, watch = true, options = {}) {
17
17
  cliOut(`Compiling app code`);
18
- let dependencyGraphDir;
19
- let dependencyGraphLocation;
20
- let oldDependencyGraph;
21
- let dependencyGraph;
22
- let importAliases;
23
- let promises;
18
+ let dependencyGraphDir = '';
19
+ let dependencyGraphLocation = '';
20
+ let oldDependencyGraph = {};
21
+ let dependencyGraph = {};
22
+ let importAliases = {};
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,18 +134,71 @@ 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
+ }
157
+ if (!watch) {
158
+ if (!initialSuccess) {
159
+ throw new AggregateError(initialFailures, 'One or more JavaScript files could not be compiled');
160
+ }
161
+ if (mode === 'dev') {
162
+ writeDependencyGraph();
163
+ }
164
+ return {
165
+ watcher: null,
166
+ copyWatcher: null,
167
+ importAliases,
168
+ initialSuccess
169
+ };
170
+ }
122
171
  const watcher = chokidar.watch(watchGlob, {
123
- ignored
172
+ ignored,
173
+ ignoreInitial: true
124
174
  //useFsEvents: false
125
175
  });
126
- watcher.on('all', async (event, file) => {
176
+ let watchCycle = Promise.resolve();
177
+ watcher.on('all', (event, file) => {
127
178
  file = slash(file);
128
- if (event === 'add') {
129
- transformFile(file);
130
- }
131
- if (event === 'change') {
132
- 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
+ });
133
202
  }
134
203
  });
135
204
  let copyWatcher = null;
@@ -155,21 +224,14 @@ export async function compileJavascript(projectDir, appConfig, codeLocation, sou
155
224
  if (copyWatcher) awaiting.set(copyWatcher, true);
156
225
  watcher.on('ready', async () => {
157
226
  //cliNews('App Built')
158
- if (mode === 'dev') {
159
- await Promise.all(promises);
160
- if (!fs.existsSync(dependencyGraphDir)) {
161
- fs.mkdirSync(dependencyGraphDir, {
162
- recursive: true
163
- });
164
- }
165
- fs.writeFileSync(dependencyGraphLocation, `export const graph = ${serializeJavascript(dependencyGraph)}`);
166
- }
227
+ if (initialSuccess) writeDependencyGraph();
167
228
  awaiting.delete(watcher);
168
229
  if (awaiting.size === 0) {
169
230
  resolve({
170
231
  watcher,
171
232
  copyWatcher,
172
- importAliases
233
+ importAliases,
234
+ initialSuccess
173
235
  });
174
236
  }
175
237
  });
@@ -181,7 +243,8 @@ export async function compileJavascript(projectDir, appConfig, codeLocation, sou
181
243
  resolve({
182
244
  watcher,
183
245
  copyWatcher,
184
- importAliases
246
+ importAliases,
247
+ initialSuccess
185
248
  });
186
249
  }
187
250
  });
@@ -1,3 +1,3 @@
1
1
  import type { FrameworkConfigComplete } from '../FrameworkConfig.js';
2
- export declare function compileStyles(projectDir: string, config: FrameworkConfigComplete, styleImportBase: string, buildLocation: string): Promise<unknown>;
2
+ export declare function compileStyles(projectDir: string, config: FrameworkConfigComplete, styleImportBase: string, buildLocation: string, watch?: boolean): Promise<unknown>;
3
3
  //# sourceMappingURL=compileStyles.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"compileStyles.d.ts","sourceRoot":"","sources":["../../src/build/compileStyles.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAA;AAiOpE,wBAAgB,aAAa,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,uBAAuB,EAAE,eAAe,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,oBA+EhI"}
1
+ {"version":3,"file":"compileStyles.d.ts","sourceRoot":"","sources":["../../src/build/compileStyles.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAA;AAiOpE,wBAAsB,aAAa,CAC/B,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,uBAAuB,EAC/B,eAAe,EAAE,MAAM,EACvB,aAAa,EAAE,MAAM,EACrB,KAAK,UAAO,oBA8Ff"}
@@ -3,6 +3,7 @@ import chokidar from 'chokidar';
3
3
  import { join, dirname, resolve } from 'path';
4
4
  import { promises as fsPromises, utimesSync } from 'fs';
5
5
  import * as sass from 'sass';
6
+ import { globby } from 'globby';
6
7
  import { staticFolder } from "../settings.js";
7
8
  import { cliError, cliOut } from "../cliOutput.js"; // eslint-disable-line @typescript-eslint/no-unused-vars
8
9
  import { throwError } from "../throwError.js";
@@ -186,7 +187,7 @@ async function processAndCopyFile(sourceLocation, targetLocation, filePathFull,
186
187
  }
187
188
  cssFiles[targetRelFile] = relFile;
188
189
  }
189
- export function compileStyles(projectDir, config, styleImportBase, buildLocation) {
190
+ export async function compileStyles(projectDir, config, styleImportBase, buildLocation, watch = true) {
190
191
  cliOut(`Compiling app stylesheets`);
191
192
  // we need to create and maintain a dependency tree for correct updating
192
193
  // we are going to save the dependencies of each file
@@ -217,6 +218,11 @@ export function compileStyles(projectDir, config, styleImportBase, buildLocation
217
218
  const watchGlob = sourceLocation + '/**/*.{css,scss,sass,less}';
218
219
  const ignoreGlob = buildLocation + '/**/*';
219
220
  debug('Styles watchGlob', watchGlob);
221
+ if (!watch) {
222
+ const files = await globby(slash(watchGlob));
223
+ await Promise.all(files.map(file => processAndCopyFile(sourceLocation, staticLocation, slash(file), styleImportBase, cssFiles, cssDependencies, cssdependers)));
224
+ return null;
225
+ }
220
226
  const watcher = chokidar.watch(watchGlob, {
221
227
  ignored: ignoreGlob
222
228
  //ignoreInitial: true
@@ -1,3 +1,3 @@
1
1
  import type { FrameworkConfigComplete } from '../FrameworkConfig.js';
2
- export declare function copyAssets(projectDir: string, config: FrameworkConfigComplete, buildLocation: string): Promise<unknown> | undefined;
2
+ export declare function copyAssets(projectDir: string, config: FrameworkConfigComplete, buildLocation: string, watch?: boolean): Promise<unknown>;
3
3
  //# sourceMappingURL=copyAssets.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"copyAssets.d.ts","sourceRoot":"","sources":["../../src/build/copyAssets.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAA;AAiBpE,wBAAgB,UAAU,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,uBAAuB,EAAE,aAAa,EAAE,MAAM,gCA+CpG"}
1
+ {"version":3,"file":"copyAssets.d.ts","sourceRoot":"","sources":["../../src/build/copyAssets.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAA;AAiBpE,wBAAsB,UAAU,CAC5B,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,uBAAuB,EAC/B,aAAa,EAAE,MAAM,EACrB,KAAK,UAAO,oBA2Df"}
@@ -2,6 +2,7 @@ import slash from 'slash';
2
2
  import chokidar from 'chokidar';
3
3
  import { join, dirname } from 'path';
4
4
  import { promises as fsPromises } from 'fs';
5
+ import { globby } from 'globby';
5
6
  import { cliOut } from "../cliOutput.js";
6
7
  async function copyFile(assetsLocation, targetLocation, filePathFull, event) {
7
8
  const relFile = filePathFull.slice(assetsLocation.length + 1);
@@ -13,7 +14,7 @@ async function copyFile(assetsLocation, targetLocation, filePathFull, event) {
13
14
  });
14
15
  return fsPromises.copyFile(filePathFull, target);
15
16
  }
16
- export function copyAssets(projectDir, config, buildLocation) {
17
+ export async function copyAssets(projectDir, config, buildLocation, watch = true) {
17
18
  if (config.assetsDir !== undefined) {
18
19
  cliOut(`Copying assets`);
19
20
  const assetsLocation = join(projectDir, config.assetsDir);
@@ -21,6 +22,11 @@ export function copyAssets(projectDir, config, buildLocation) {
21
22
  //console.log('copy assets from', assetsLocation, 'to', targetLocation)
22
23
  const watchGlob = assetsLocation + '/**/*';
23
24
  //const ignoreGlob = buildLocation + '/**/*'
25
+ if (!watch) {
26
+ const files = await globby(slash(watchGlob));
27
+ await Promise.all(files.map(file => copyFile(assetsLocation, targetLocation, slash(file), 'add')));
28
+ return null;
29
+ }
24
30
  const watcher = chokidar.watch(watchGlob, {
25
31
  //ignored: ignoreGlob,
26
32
  //ignoreInitial: true
@@ -1,3 +1,3 @@
1
1
  import type { FrameworkConfigComplete } from '../FrameworkConfig.js';
2
- export declare function copyPublicFiles(projectDir: string, config: FrameworkConfigComplete, buildLocation: string): Promise<unknown>;
2
+ export declare function copyPublicFiles(projectDir: string, config: FrameworkConfigComplete, buildLocation: string, watch?: boolean): Promise<unknown>;
3
3
  //# sourceMappingURL=copyPublicFiles.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"copyPublicFiles.d.ts","sourceRoot":"","sources":["../../src/build/copyPublicFiles.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAA;AAiBpE,wBAAgB,eAAe,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,uBAAuB,EAAE,aAAa,EAAE,MAAM,oBAgDzG"}
1
+ {"version":3,"file":"copyPublicFiles.d.ts","sourceRoot":"","sources":["../../src/build/copyPublicFiles.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAA;AAiBpE,wBAAsB,eAAe,CACjC,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,uBAAuB,EAC/B,aAAa,EAAE,MAAM,EACrB,KAAK,UAAO,oBA4Df"}
@@ -2,6 +2,7 @@ import slash from 'slash';
2
2
  import chokidar from 'chokidar';
3
3
  import { join, dirname } from 'path';
4
4
  import { promises as fsPromises } from 'fs';
5
+ import { globby } from 'globby';
5
6
  import { cliOut } from "../cliOutput.js";
6
7
  async function copyFile(assetsLocation, targetLocation, filePathFull, event) {
7
8
  const relFile = filePathFull.slice(assetsLocation.length + 1);
@@ -13,7 +14,7 @@ async function copyFile(assetsLocation, targetLocation, filePathFull, event) {
13
14
  });
14
15
  return fsPromises.copyFile(filePathFull, target);
15
16
  }
16
- export function copyPublicFiles(projectDir, config, buildLocation) {
17
+ export async function copyPublicFiles(projectDir, config, buildLocation, watch = true) {
17
18
  //if ( config.publicDir !== undefined ) {
18
19
  cliOut(`Copying public files`);
19
20
  const publicLocation = config.publicDir !== undefined ? join(projectDir, config.publicDir) : join(projectDir, 'public');
@@ -22,6 +23,11 @@ export function copyPublicFiles(projectDir, config, buildLocation) {
22
23
  //console.log('copy assets from', publicLocation, 'to', targetLocation)
23
24
  const watchGlob = publicLocation + '/**/*';
24
25
  //const ignoreGlob = buildLocation + '/**/*'
26
+ if (!watch) {
27
+ const files = await globby(slash(watchGlob));
28
+ await Promise.all(files.map(file => copyFile(publicLocation, targetLocation, slash(file), 'add')));
29
+ return null;
30
+ }
25
31
  const watcher = chokidar.watch(watchGlob, {
26
32
  //ignored: ignoreGlob,
27
33
  //ignoreInitial: true
@@ -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,
@@ -507,15 +507,7 @@ async function hydrateNodeSingle(node, parentElement, domPointer, instance, meta
507
507
  renderedChildren = await hydrateNode(children, parentElement, childDomPointer, instance, meta);
508
508
  }
509
509
  if (node[$type] === 'select' && node[$props].value !== undefined && node[$props].value !== null) {
510
- const options = domNode.options;
511
- const value = String(node[$props].value);
512
- for (let i = options.length - 1; i >= 0; i--) {
513
- const option = options[i];
514
- if (option.value === value) {
515
- option.selected = true;
516
- break;
517
- }
518
- }
510
+ domNode.value = String(node[$props].value);
519
511
  }
520
512
  // note that we have left the form
521
513
  if (node[$type] === 'form') meta.insideForm = false;
@@ -662,13 +654,6 @@ function hydrateAttributes(node, domNode) {
662
654
  domNode[htmlEventHandlerKey(eventName)] = handler;
663
655
  }
664
656
  }
665
- if (node[$type] === 'option') {
666
- const option = domNode;
667
- const select = option.closest('select');
668
- if (select !== null && select.hasAttribute('value') && select.getAttribute('value') === option.value) {
669
- option.selected = true;
670
- }
671
- }
672
657
  debug('--');
673
658
  }
674
659
  // onChange -> add
@@ -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';
@@ -1 +1 @@
1
- {"version":3,"file":"integrateUpdateVdom.d.ts","sourceRoot":"","sources":["../../src/update/integrateUpdateVdom.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAC7C,OAAO,EACH,WAAW,EAAwC,eAAe,EAElE,uBAAuB,EAG1B,MAAM,mBAAmB,CAAA;AAC1B,OAAO,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAA;AAKlD,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAA;AAEvD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AAKjD,OAAO,EAKyB,4BAA4B,EAI3D,MAAM,2BAA2B,CAAA;AAClC,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAYhD,MAAM,MAAM,mBAAmB,GAAG,WAAW,GAAG;IAC5C,wBAAwB,EAAE,CAAC,IAAI,EAAE,WAAW,EAAE,EAAE,EAAE,UAAU,KAAK,GAAG,CAAA;IACpE,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;CACzB,CAAA;AAYD,wBAAsB,0BAA0B,CAC5C,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,WAAW,GAC/C,OAAO,CAAC,YAAY,CAAC,CA0GvB;AA+mBD,wBAAgB,eAAe,CAAC,IAAI,EAAE,eAAe,EAAE,UAAU,EAAE,WAAW,QAkK7E;AAuWD,KAAK,2BAA2B,GAAG;IAC/B,MAAM,EAAE,eAAe,CAAA;IACvB,QAAQ,EAAE,QAAQ,CAAC;IACnB,IAAI,EAAE,uBAAuB,CAAC;IAE9B,UAAU,EAAE,UAAU,CAAA;CACzB,CAAA;AACD,wBAAsB,uBAAuB,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,UAAU,EAAE,EAAE,2BAA2B,GAC3G,OAAO,CAAC,4BAA4B,CAAC,CAU1C"}
1
+ {"version":3,"file":"integrateUpdateVdom.d.ts","sourceRoot":"","sources":["../../src/update/integrateUpdateVdom.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAC7C,OAAO,EACH,WAAW,EAAwC,eAAe,EAElE,uBAAuB,EAG1B,MAAM,mBAAmB,CAAA;AAC1B,OAAO,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAA;AAKlD,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAA;AAEvD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AAKjD,OAAO,EAKyB,4BAA4B,EAI3D,MAAM,2BAA2B,CAAA;AAClC,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAYhD,MAAM,MAAM,mBAAmB,GAAG,WAAW,GAAG;IAC5C,wBAAwB,EAAE,CAAC,IAAI,EAAE,WAAW,EAAE,EAAE,EAAE,UAAU,KAAK,GAAG,CAAA;IACpE,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;CACzB,CAAA;AAYD,wBAAsB,0BAA0B,CAC5C,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,WAAW,GAC/C,OAAO,CAAC,YAAY,CAAC,CA0GvB;AAkmBD,wBAAgB,eAAe,CAAC,IAAI,EAAE,eAAe,EAAE,UAAU,EAAE,WAAW,QAkK7E;AAwUD,KAAK,2BAA2B,GAAG;IAC/B,MAAM,EAAE,eAAe,CAAA;IACvB,QAAQ,EAAE,QAAQ,CAAC;IACnB,IAAI,EAAE,uBAAuB,CAAC;IAE9B,UAAU,EAAE,UAAU,CAAA;CACzB,CAAA;AACD,wBAAsB,uBAAuB,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,UAAU,EAAE,EAAE,2BAA2B,GAC3G,OAAO,CAAC,4BAA4B,CAAC,CAU1C"}
@@ -410,23 +410,11 @@ async function updateHtmlElement(tungstenElement, instance, newNode, oldNode, do
410
410
  domPointer: new DomPointer(domNode, 0),
411
411
  parentNode: newNode
412
412
  });
413
- if (newNode[$type] === 'select') {
414
- // if we updated a select element
415
- // if the value changed, we need to update the options
416
- // alternatively the options might have changed, also requiring
417
- // updates to `selected`
418
- // if the options update without the select updating, then they will need to look-back to find the value of the select
419
- if (newNode[$props].value !== undefined && newNode[$props].value !== null && String(newNode[$props].value) !== String(oldNode[$props].value)) {
420
- const options = domNode.options;
421
- const value = String(newNode[$props].value);
422
- for (let i = options.length - 1; i >= 0; i--) {
423
- const option = options[i];
424
- if (option.value === value) {
425
- option.selected = true;
426
- break;
427
- }
428
- }
429
- }
413
+ // Reapply the controlled value after reconciling the options. Updating the
414
+ // option collection can change the browser's selection even when the
415
+ // virtual select value itself has not changed.
416
+ if (newNode[$type] === 'select' && newNode[$props].value !== undefined && newNode[$props].value !== null) {
417
+ domNode.value = String(newNode[$props].value);
430
418
  }
431
419
  return makeRenderedContentNodeHtml(newNode, domNode, renderedChildren);
432
420
  }
@@ -800,22 +788,7 @@ async function createHtmlElement(tungstenElement, instance, node, domPointer, pa
800
788
  });
801
789
  if (node[$type] === 'select') {
802
790
  if (node[$props].value !== undefined && node[$props].value !== null) {
803
- const options = htmlEl.options;
804
- const value = String(node[$props].value);
805
- for (let i = options.length - 1; i >= 0; i--) {
806
- const option = options[i];
807
- if (option.value === value) {
808
- option.selected = true;
809
- break;
810
- }
811
- }
812
- }
813
- }
814
- if (node[$type] === 'option') {
815
- const option = htmlEl;
816
- const select = option.closest('select');
817
- if (select !== null && select.hasAttribute('value') && select.getAttribute('value') === option.value) {
818
- option.selected = true;
791
+ htmlEl.value = String(node[$props].value);
819
792
  }
820
793
  }
821
794
  return {
@@ -938,13 +911,6 @@ function updateAttributes(node, oldNode, domNodeHTMLElement) {
938
911
  }
939
912
  }
940
913
  }
941
- if (node[$type] === 'option') {
942
- const option = domNode;
943
- const select = option.closest('select');
944
- if (select !== null && select.hasAttribute('value') && select.getAttribute('value') === option.value) {
945
- option.selected = true;
946
- }
947
- }
948
914
  domNode.__tungsten_oldAttributes = newAttributes;
949
915
  return newAttributes;
950
916
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tungsten",
3
- "version": "0.2.5",
3
+ "version": "0.2.7",
4
4
  "description": "",
5
5
  "type": "module",
6
6
  "bin": {
package/readme.md CHANGED
@@ -1,3 +1,60 @@
1
1
  # Tungsten Frontend Framework
2
2
 
3
- [Docs](https://robertsandiford.co.uk/tungsten)
3
+ [Docs](https://robertsandiford.co.uk/tungsten)
4
+
5
+ ## Preparing code for tests
6
+
7
+ Run a one-shot development compilation without starting a server:
8
+
9
+ ```sh
10
+ tungsten compile
11
+ ```
12
+
13
+ By default this compiles JavaScript (including JSX and Tungsten's Babel
14
+ transforms), stylesheets, client support files, assets, and public files into
15
+ `.tungsten/dev`.
16
+ Each selected target's existing generated output is cleaned before the initial
17
+ compilation, including when watch mode is used. Pass `--no-clean` to preserve
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.
30
+ Limit the work with one or more options:
31
+
32
+ ```sh
33
+ tungsten compile --js
34
+ tungsten compile --css
35
+ tungsten compile --client
36
+ tungsten compile --assets
37
+ tungsten compile --public
38
+ tungsten compile --js --css
39
+ ```
40
+
41
+ `--all` explicitly selects all five targets.
42
+
43
+ Add `--watch` to keep the JavaScript, stylesheet, asset, and/or public-file
44
+ compiler running after the initial pass. Client support files are still
45
+ generated once:
46
+
47
+ ```sh
48
+ tungsten compile --watch
49
+ tungsten compile --js --watch
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
+ ```