cayo 0.9.10 → 1.0.0

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 (122) hide show
  1. package/README.md +504 -5
  2. package/cayo.js +1 -298
  3. package/devlog.md +177 -0
  4. package/dist/cayo.svelte.js +80 -0
  5. package/dist/entry.svelte.js +16 -0
  6. package/dist/index.js +2 -0
  7. package/docs/config-reference.md +349 -0
  8. package/docs/how-cayo-works.md +28 -0
  9. package/docs/why-i-created-cayo.md +21 -0
  10. package/lib/cli/build.js +34 -0
  11. package/lib/cli/cli.js +152 -0
  12. package/lib/cli/dev.js +12 -0
  13. package/lib/cli/serve.js +25 -0
  14. package/lib/cli/watch.js +125 -0
  15. package/lib/core/bundle.js +155 -0
  16. package/lib/core/codegen.js +156 -0
  17. package/lib/core/compile/cayos.js +65 -0
  18. package/lib/core/compile/index.js +3 -0
  19. package/lib/core/compile/pages.js +61 -0
  20. package/lib/core/compile/template.js +24 -0
  21. package/lib/core/component.js +62 -0
  22. package/lib/core/config.js +206 -0
  23. package/lib/core/dependencies.js +167 -0
  24. package/lib/core/entry.js +24 -0
  25. package/lib/core/files.js +99 -0
  26. package/lib/core/logger.js +47 -0
  27. package/lib/core/page.js +59 -0
  28. package/lib/core/render/prerender.js +240 -0
  29. package/lib/core/render/renderer.js +52 -0
  30. package/lib/core/utils.js +60 -0
  31. package/package.json +21 -10
  32. package/scripts/build.js +60 -0
  33. package/src/cayo-warnings.js +37 -0
  34. package/src/cayo.svelte +36 -0
  35. package/src/entry.svelte +6 -0
  36. package/template/cayo.config.js +3 -0
  37. package/template/package-lock.json +4027 -0
  38. package/template/package.json +10 -0
  39. package/template/public/vite.svg +1 -0
  40. package/{tests/basic cases (old)/src/__index.svelte → template/src/__template.svelte} +3 -6
  41. package/template/src/components/counter.cayo.svelte +27 -0
  42. package/template/src/index.js +4 -0
  43. package/template/src/pages/index.svelte +15 -0
  44. package/template/src/style.css +13 -0
  45. package/lib/cli.js +0 -69
  46. package/lib/codegen.js +0 -79
  47. package/lib/components/Cayo.svelte +0 -25
  48. package/lib/config.js +0 -155
  49. package/lib/files.js +0 -84
  50. package/lib/prerender.js +0 -181
  51. package/lib/renderer.js +0 -49
  52. package/lib/runtime.js +0 -6
  53. package/lib/utils.js +0 -126
  54. package/lib/vite.config.js +0 -16
  55. package/notes.md +0 -3
  56. package/test/cayo.config.js +0 -35
  57. package/test/public/assets/cow.js +0 -1
  58. package/test/public/images/app-icon.png +0 -0
  59. package/test/src/__layout.svelte +0 -20
  60. package/test/src/components/Cool.cayo.svelte +0 -5
  61. package/test/src/components/Some.svelte +0 -1
  62. package/test/src/components/Test.cayo.svelte +0 -5
  63. package/test/src/index.js +0 -17
  64. package/test/src/main2.js +0 -1
  65. package/test/src/pages/hey.svelte +0 -8
  66. package/test/src/pages/howdy.svelte +0 -11
  67. package/test/src/pages/index.svelte +0 -38
  68. package/test/src/pages/some/page.svelte +0 -2
  69. package/tests/asset-dir/cayo.config.js +0 -38
  70. package/tests/asset-dir/package-lock.json +0 -1435
  71. package/tests/asset-dir/package.json +0 -19
  72. package/tests/asset-dir/public/images/app-icon.png +0 -0
  73. package/tests/asset-dir/src/__layout.svelte +0 -20
  74. package/tests/asset-dir/src/components/CayoExample.svelte +0 -5
  75. package/tests/asset-dir/src/components/Some.cayo.svelte +0 -6
  76. package/tests/asset-dir/src/index.js +0 -5
  77. package/tests/asset-dir/src/pages/index.svelte +0 -19
  78. package/tests/base-path/cayo.config.js +0 -36
  79. package/tests/base-path/package-lock.json +0 -1435
  80. package/tests/base-path/package.json +0 -19
  81. package/tests/base-path/public/assets/cow.js +0 -1
  82. package/tests/base-path/public/images/app-icon.png +0 -0
  83. package/tests/base-path/src/__layout.svelte +0 -20
  84. package/tests/base-path/src/components/CayoExample.svelte +0 -5
  85. package/tests/base-path/src/components/Some.cayo.svelte +0 -6
  86. package/tests/base-path/src/index.js +0 -5
  87. package/tests/base-path/src/pages/howdy.svelte +0 -12
  88. package/tests/base-path/src/pages/index.svelte +0 -20
  89. package/tests/basic/notcayo.config.js +0 -35
  90. package/tests/basic/package-lock.json +0 -1435
  91. package/tests/basic/package.json +0 -19
  92. package/tests/basic/public/assets/cow.js +0 -1
  93. package/tests/basic/public/images/app-icon.png +0 -0
  94. package/tests/basic/src/__layout.svelte +0 -20
  95. package/tests/basic/src/components/Cool.cayo.svelte +0 -4
  96. package/tests/basic/src/components/Some.svelte +0 -1
  97. package/tests/basic/src/index.js +0 -5
  98. package/tests/basic/src/main2.js +0 -1
  99. package/tests/basic/src/pages/hey.svelte +0 -8
  100. package/tests/basic/src/pages/howdy.svelte +0 -11
  101. package/tests/basic/src/pages/index.svelte +0 -33
  102. package/tests/basic/src/pages/some/some.svelte +0 -2
  103. package/tests/basic cases (old)/src/components/Cool.cayo.svelte +0 -4
  104. package/tests/basic cases (old)/src/components/Some.svelte +0 -1
  105. package/tests/basic cases (old)/src/components/dir/Cool.cayo.svelte +0 -4
  106. package/tests/basic cases (old)/src/main.js +0 -1
  107. package/tests/basic cases (old)/src/main2.js +0 -1
  108. package/tests/basic cases (old)/src/pages/hey.svelte +0 -2
  109. package/tests/basic cases (old)/src/pages/howdy.svelte +0 -11
  110. package/tests/basic cases (old)/src/pages/index.svelte +0 -27
  111. package/tests/nested-pages/cayo.config.js +0 -35
  112. package/tests/nested-pages/package-lock.json +0 -1435
  113. package/tests/nested-pages/package.json +0 -19
  114. package/tests/nested-pages/public/assets/cow.js +0 -1
  115. package/tests/nested-pages/public/images/app-icon.png +0 -0
  116. package/tests/nested-pages/src/__layout.svelte +0 -20
  117. package/tests/nested-pages/src/components/Cool.cayo.svelte +0 -4
  118. package/tests/nested-pages/src/index.js +0 -5
  119. package/tests/nested-pages/src/main2.js +0 -1
  120. package/tests/nested-pages/src/pages/index.svelte +0 -18
  121. package/tests/nested-pages/src/pages/some/other/page.svelte +0 -7
  122. package/tests/nested-pages/src/pages/some/page.svelte +0 -6
@@ -0,0 +1,125 @@
1
+ import path from 'path';
2
+ import chokidar from 'chokidar';
3
+ import chalk from 'chalk';
4
+ import logger from '#core/logger.js';
5
+ import * as compile from '#core/compile/index.js';
6
+ import { findDependentPages } from '#core/dependencies.js';
7
+ import { writePageFiles, writeEntryFile } from '#core/files.js';
8
+ import { debugStats } from '#core/utils.js';
9
+
10
+ export function watch(_cayo) {
11
+ const { config } = _cayo;
12
+
13
+ const watcher = chokidar.watch(config.src, {
14
+ // awaitWriteFinish: {
15
+ // stabilityThreshold: 1,
16
+ // pollInterval: 250
17
+ // },
18
+ });
19
+
20
+ const configWatcher = chokidar.watch(path.resolve(config.projectRoot, './cayo.config.js'));
21
+
22
+ configWatcher.on('change', (filepath) => {
23
+ logger.log.info(
24
+ chalk.yellow(`config updated... restart dev server to use new config.`),
25
+ { timestamp: true, clear: true, }
26
+ );
27
+ })
28
+
29
+ const logChange = (type, filepath = '') => {
30
+ if (filepath !== '') {
31
+ if (type === 'component' || 'cayo') {
32
+ filepath = filepath.replace(config.components, '');
33
+ } else if (type === 'page') {
34
+ filepath = filepath.replace(config.pages, '');
35
+ }
36
+ }
37
+
38
+ logger.log.info(
39
+ `${type} updated ${chalk.dim(filepath)}`,
40
+ { timestamp: true, clear: true, }
41
+ );
42
+ }
43
+
44
+ watcher.on('change', async (filepath) => {
45
+ try {
46
+ // Handle Svelte files
47
+ if (filepath.endsWith('.svelte')) {
48
+ // Handle Template
49
+ if (filepath.endsWith(`${config.templateName}.svelte`)) {
50
+ logChange('template');
51
+ await handleTemplate(_cayo);
52
+
53
+ // Handle Pages
54
+ } else if (filepath.startsWith(config.pages)) {
55
+ logChange('page', filepath);
56
+ await handlePage(filepath, _cayo);
57
+
58
+ // Handle Cayos
59
+ } else if (filepath.includes(`.${config.cayoComponentInfix}`)) {
60
+ logChange('cayo', filepath);
61
+ await handleCayo(filepath, _cayo);
62
+
63
+ // Handle Components
64
+ } else if (filepath.startsWith(config.components)) {
65
+ logChange('component', filepath);
66
+ await handleComponent(filepath, _cayo);
67
+ }
68
+ // Handle everything else
69
+ } else {
70
+ if (_cayo.stats.dependencies.entries[filepath]) {
71
+ logChange('entry', filepath);
72
+ await handleEntry(filepath, _cayo);
73
+ } else {
74
+ await handleOther(filepath, _cayo);
75
+ }
76
+ }
77
+ } catch (err) {
78
+ logger.error(err);
79
+ }
80
+ });
81
+ }
82
+
83
+ async function handleTemplate(_cayo) {
84
+ await compile.template(_cayo);
85
+ for (const [key] of _cayo.pages) {
86
+ await handlePage(key, _cayo);
87
+ }
88
+ }
89
+
90
+ async function handleCayo(filepath, _cayo) {
91
+ await handleOther(filepath, _cayo);
92
+ }
93
+
94
+ async function handleComponent(filepath, _cayo) {
95
+ await handleOther(filepath, _cayo);
96
+ }
97
+
98
+ async function handleOther(filepath, _cayo) {
99
+ const dependentPages = findDependentPages(filepath, _cayo);
100
+ for (const page of dependentPages) {
101
+ await handlePage(page, _cayo);
102
+ }
103
+ }
104
+
105
+ async function handleEntry(filepath, _cayo) {
106
+ for (const [, page] of _cayo.pages) {
107
+ if (filepath === page.result.entry.path) {
108
+ await writeEntryFile(page, _cayo);
109
+ }
110
+ }
111
+ }
112
+
113
+ async function handlePage(filepath, _cayo) {
114
+ const { pages } = _cayo;
115
+
116
+ const page = (await compile.pages([filepath], _cayo))[0];
117
+ pages.set(filepath, page);
118
+ await page.render(_cayo, { load: true });
119
+
120
+ if (_cayo.config.debug) {
121
+ debugStats(_cayo);
122
+ }
123
+
124
+ await writePageFiles(page, _cayo);
125
+ }
@@ -0,0 +1,155 @@
1
+ import fs, { pathExists } from 'fs-extra';
2
+ import { rollup } from 'rollup';
3
+ import svelte from 'rollup-plugin-svelte';
4
+ import css from 'rollup-plugin-import-css';
5
+ import json from '@rollup/plugin-json';
6
+
7
+ function inputOptions(input) {
8
+ return {
9
+ input,
10
+ onwarn: function ( message ) {
11
+ if ( /external dependency/.test( message ) ) return;
12
+ },
13
+ };
14
+ }
15
+
16
+ function defaultRollupPlugins() {
17
+ return [css(), json()];
18
+ }
19
+
20
+ function userRollupPlugins(config) {
21
+ return config.vite.rollupOptions.plugins;
22
+ }
23
+
24
+ export async function getDeps(input, config) {
25
+ let bundle;
26
+ // User-defined preprocessors
27
+ let preprocessors = config.svelte.preprocess.length > 0
28
+ ? config.svelte.preprocess
29
+ : [config.svelte.preprocess];
30
+
31
+ const options = {
32
+ ...inputOptions(input),
33
+ plugins: [
34
+ svelte({
35
+ preprocess: [
36
+ ...preprocessors,
37
+ ],
38
+ }),
39
+ ...defaultRollupPlugins(),
40
+ ...userRollupPlugins(config),
41
+ ]
42
+ }
43
+ try {
44
+ // Create a bundle
45
+ bundle = await rollup(options);
46
+ if (bundle) {
47
+ await bundle.close();
48
+ }
49
+ if (bundle) {
50
+ await bundle.close();
51
+ }
52
+ // An array of file names this bundle depends on
53
+ return bundle.watchFiles.filter(dep => (dep !== input));
54
+
55
+ } catch (err) {
56
+ let errorMessage = `Parsing dependencies of '${input.replace(config.src, 'src/')}'`;
57
+ if (!fs.pathExistsSync(input)) {
58
+ errorMessage += `\n> File does not exist: '${input}'.`;
59
+ } else {
60
+ errorMessage += `\n> Rollup Error: ${err.code}`;
61
+ if (err.code === 'PLUGIN_ERROR') {
62
+ errorMessage += `\n> ${err.plugin} (Error code: ${err.pluginCode})`;
63
+ }
64
+ errorMessage += `\n> Trace: ${err.stack}`;
65
+ }
66
+
67
+ throw new Error(errorMessage, { cause: err });
68
+ }
69
+
70
+ }
71
+
72
+ export async function build(input, config, type = 'page') {
73
+ const ssr = (type === 'page' || type === 'template');
74
+ const requiredCompilerOptions = {
75
+ generate: ssr ? 'ssr' : 'dom',
76
+ hydratable: ssr ? false : true,
77
+ }
78
+
79
+ let bundle;
80
+ let output = {
81
+ js: { code: '' },
82
+ css: { code: '' },
83
+ dependencies: [],
84
+ };
85
+ // User-defined preprocessors
86
+ let preprocessors = config.svelte.preprocess.length > 0
87
+ ? config.svelte.preprocess
88
+ : [config.svelte.preprocess];
89
+
90
+ const options = {
91
+ ...inputOptions(input),
92
+ plugins: [
93
+ svelte({
94
+ preprocess: [
95
+ ...preprocessors,
96
+ ],
97
+ compilerOptions: {
98
+ preserveComments: true,
99
+ preserveWhitespace: true,
100
+ ...config.svelte.compilerOptions,
101
+ ...requiredCompilerOptions,
102
+ },
103
+ extensions: config.svelte.extensions,
104
+ }),
105
+ ...defaultRollupPlugins(),
106
+ ...userRollupPlugins(config),
107
+ ]
108
+ }
109
+
110
+ try {
111
+ bundle = await rollup(options);
112
+ output.dependencies = bundle.watchFiles.filter(dep => (dep !== input));
113
+ const { js, css } = await generateOutputs(bundle, input);
114
+ output.js = js;
115
+ output.css = css;
116
+
117
+ if (bundle) {
118
+ await bundle.close();
119
+ }
120
+
121
+ return output;
122
+
123
+ } catch (err) {
124
+ let absoluteBase = type !== 'cayo'
125
+ ? config[`${type}s`]
126
+ : pathExists.join(config.components);
127
+
128
+ let relativeFilePath = input.replace(absoluteBase, '');
129
+ let errorMessage = `Could not compile ${type}: '${relativeFilePath}'`;
130
+ errorMessage += `\n> Rollup Error: ${err.code}`;
131
+ if (err.code === 'PLUGIN_ERROR') {
132
+ errorMessage += `\n> ${err.plugin} (Error code: ${err.pluginCode})`;
133
+ }
134
+ errorMessage += `\n\n> Source: ${input}`;
135
+ errorMessage += `\n${err.frame}`
136
+ errorMessage += `\n> ${err.stack}`;
137
+
138
+ throw new Error(errorMessage, { cause: err });
139
+ }
140
+ }
141
+
142
+ async function generateOutputs(bundle, input) {
143
+ const outputOptions = { }
144
+ const { output } = await bundle.generate(outputOptions);
145
+ return {
146
+ js: {
147
+ code: output[0].code,
148
+ },
149
+ css: {
150
+ code: output[1] && output[1].fileName === 'bundle.css'
151
+ ? output[1].source
152
+ : ''
153
+ }
154
+ };
155
+ }
@@ -0,0 +1,156 @@
1
+ import path from 'path';
2
+ import chalk from 'chalk';
3
+
4
+ // Generate runtime helper that finds and parses a component instance's prop data
5
+ export function generateGetProps() {
6
+ return (
7
+ `
8
+ function getProps(cayoElement) {
9
+ const json = cayoElement.dataset.cayoProps;
10
+ return JSON.parse(json);
11
+ }
12
+ `
13
+ );
14
+ }
15
+
16
+ // Generate the Cayo Runtime which is unique per page to render the cayos on the page
17
+ export function generateCayoRuntime(components, fileName, _cayo) {
18
+ const { config, __VERSION__ } = _cayo;
19
+ let code = '';
20
+ let instances = '';
21
+ // Add banner
22
+ code += `/* ${fileName} generated by Cayo v${__VERSION__} */\n`;
23
+
24
+ if (Object.keys(components).length !== 0) {
25
+ // TODO: add this path to config (internal only)
26
+ const componentPathBase = path.resolve(config.cayoPath, './__cayo/components');
27
+ Object.entries(components).forEach(([name, ids]) => {
28
+ // Add component dependency import
29
+ code += `import ${name} from '${componentPathBase}/${name}.svelte.js';\n`;
30
+ // Generate component instances
31
+ ids.forEach(id => {
32
+ instances += generateComponentInstance(id, name)
33
+ });
34
+ });
35
+
36
+ // Add getProps (used by component instances)
37
+ code += generateGetProps();
38
+ } else {
39
+ instances += ` // No cayo component instances found in page HTML`;
40
+ }
41
+
42
+ // Add main render, which runs the component instantiations
43
+ code += generateRender(instances);
44
+
45
+ return { code };
46
+ }
47
+
48
+ function generateRender(contents) {
49
+ return (
50
+ `
51
+ export default function render(cb) {
52
+ var target = cb ? cb : (node) => node;
53
+ let cayos = {};
54
+ ${contents}
55
+ return cayos;
56
+ }
57
+ `
58
+ );
59
+ }
60
+
61
+ // Generate the code to wrap component instances in an event listener wrapper
62
+ export function generateComponentInstanceWrapper(contents) {
63
+ return (
64
+ `
65
+ document.addEventListener('DOMContentLoaded', function() {
66
+ ${contents}
67
+ });
68
+ `
69
+ );
70
+ }
71
+
72
+ // Generate the code for a component instance
73
+ export function generateComponentInstance(cayoId, componentName) {
74
+ return (
75
+ `
76
+ cayos['${cayoId}'] = {};
77
+ cayos['${cayoId}'].target = document.querySelector('[data-cayo-id="${cayoId}"]');
78
+ cayos['${cayoId}'].instance = new ${componentName}({
79
+ target: target(cayos['${cayoId}'].target),
80
+ hydrate: true,
81
+ props: getProps(cayos['${cayoId}'].target),
82
+ });
83
+ `
84
+ );
85
+ }
86
+
87
+ // Generate the code to import the the generated Cayo Runtime file
88
+ export function generateCayoRuntimeImport() {
89
+ return `import { default as renderCayos } from './cayo-runtime.js';\n`
90
+ }
91
+
92
+ // TODO: add links to relevant docs
93
+ // Generate console warnings that need to show in the browser
94
+ export function generateRuntimeIssuesScript(runtime, issues, type) {
95
+ const { config, document, page } = runtime;
96
+ const script = document.createElement('script');
97
+ const logs = [];
98
+
99
+ // Formatting and label stuff
100
+ let prefix = 'Warning';
101
+ let f_log = (str) => str;
102
+ let f_prefix = prefix
103
+ let consoleType = 'log';
104
+ if (type === 'warning') {
105
+ prefix = 'Warning';
106
+ f_log = chalk.yellow;
107
+ f_prefix = chalk.yellow.bold(prefix);
108
+ consoleType = 'warn';
109
+ } else if (type === 'error') {
110
+ prefix = 'Error';
111
+ f_log = chalk.redBright;
112
+ f_prefix = chalk.redBright.bold(prefix);
113
+ consoleType = 'error';
114
+ }
115
+
116
+ const {
117
+ cayos: cayoIssues,
118
+ page: pageIssues,
119
+ } = issues;
120
+
121
+ script.innerHTML = `/* ${prefix}s for this page. See issues in console. */\n`;
122
+
123
+ // Handle issues derived during initial compilation of the cayo instance
124
+ if (Object.keys(cayoIssues).length > 0) {
125
+ for (const cayoId in cayoIssues) {
126
+ let message = `Cayo ${prefix}: Cayo '${cayoId}' has runtime issues.\n\n`;
127
+ for (const key in cayoIssues[cayoId]) {
128
+ const issue = cayoIssues[cayoId][key];
129
+ message += `${issue.title}: ${issue.message}\n\n`;
130
+ if (cayoId !== 'undefined') {
131
+ message += `Hint: review instances of <Cayo src="${issue.src}"> intended to be rendered on page '${page.sourcePath.replace(config.pages, '')}'\n`;
132
+ } else {
133
+ message += `Hint: review instances of <Cayo src={<undefined>}> or <Cayo> without a src prop intended to be rendered on page '${page.sourcePath.replace(config.pages, '')}'\n`;
134
+ }
135
+ if (issue.log) {
136
+ logs.push(`${f_log(`${f_prefix}: ${issue.log}`)} ${chalk.dim(`${page.name}`)}`);
137
+ }
138
+ }
139
+ script.innerHTML += `console.${consoleType}(\`${message}\`);\n`;
140
+ }
141
+ }
142
+ // Handle issues derived from parsing the rendered HTML page
143
+ if (Object.keys(pageIssues).length > 0) {
144
+ for (const key in pageIssues) {
145
+ const issue = pageIssues[key];
146
+ let message = `${prefix}: page '${page.name}' has runtime issues.\n\n`;
147
+ message += `${issue.title}: ${issue.message}\n\n`;
148
+ script.innerHTML += `console.${consoleType}(\`${message}\`);\n`;
149
+ if (issue.log) {
150
+ logs.push(`${f_log(`${f_prefix}: ${issue.log}`)} ${chalk.dim(`${page.name}`)}`);
151
+ }
152
+ }
153
+ }
154
+
155
+ return { script, logs };
156
+ }
@@ -0,0 +1,65 @@
1
+ import fs from 'fs-extra';
2
+ import path from 'path';
3
+
4
+ import { handleDependencies } from '../dependencies.js';
5
+ import { Component } from '../component.js';
6
+ import { build } from '../bundle.js';
7
+ import logger from '../logger.js';
8
+
9
+ export async function compileCayos(components, _cayo) {
10
+ const compiledComponents = [];
11
+
12
+ if (components === null) {
13
+ components = _cayo.stats.cayoComponents;
14
+ }
15
+
16
+ for (const [name, cayo] of Object.entries(components)) {
17
+ if (!fs.pathExistsSync(cayo.src)) {
18
+ let relativeFilePath = cayo.src.replace(_cayo.config.projectRoot, '.');
19
+ let errorMessage = `Could not compile cayo. Path does not exist: '${relativeFilePath}'`
20
+ throw new Error(errorMessage);
21
+ } else {
22
+ compiledComponents.push(
23
+ await compileCayo(name, cayo, _cayo)
24
+ );
25
+ }
26
+
27
+ }
28
+
29
+ return compiledComponents;
30
+ }
31
+
32
+ export async function compileCayo(name, cayo, _cayo) {
33
+ const { config } = _cayo;
34
+ const { src: filepath } = cayo;
35
+ let filename = filepath.replace(`${config.components}`, '');
36
+ const { js, css, dependencies } = await build(filepath, config, 'cayo');
37
+
38
+ const depender = {
39
+ type: 'component',
40
+ path: filepath,
41
+ dependencies,
42
+ }
43
+
44
+ try {
45
+ await handleDependencies(depender, _cayo);
46
+
47
+ // Write bundle to a file
48
+ let outputPath = path.resolve(
49
+ config.cayoPath,
50
+ `./__cayo/components/${name}.svelte.js`
51
+ );
52
+
53
+ await fs.outputFile(outputPath, js.code);
54
+
55
+ // Create new Component and add it to the runtime object
56
+ const cayo = new Component(name, { js, css }, filepath, outputPath, dependencies, config);
57
+ _cayo.components.set(filepath, cayo);
58
+
59
+ return cayo;
60
+
61
+ } catch (err) {
62
+ throw new Error(`Compiling Cayo Component: ${filename}\n`, {cause: err});
63
+ }
64
+ }
65
+
@@ -0,0 +1,3 @@
1
+ export { compileTemplate as template } from './template.js';
2
+ export { compilePages as pages } from './pages.js';
3
+ export { compileCayos as cayos } from './cayos.js';
@@ -0,0 +1,61 @@
1
+ import fs from 'fs-extra';
2
+ import fg from 'fast-glob';
3
+ import path from 'path';
4
+
5
+ import { handleDependencies } from '../dependencies.js';
6
+ import { Page } from '../page.js';
7
+ import { build } from '../bundle.js';
8
+
9
+ export async function compilePages(pagePaths, _cayo) {
10
+ const compiledPages = [];
11
+
12
+ if (pagePaths === null) {
13
+ pagePaths = await getPagePaths(_cayo.config.pages);
14
+ }
15
+
16
+ for await (const pagePath of pagePaths) {
17
+ compiledPages.push(
18
+ await compilePage(pagePath, _cayo)
19
+ );
20
+ }
21
+
22
+ return compiledPages;
23
+ }
24
+
25
+ async function compilePage(filepath, _cayo) {
26
+ const { template, config } = _cayo;
27
+ let filename = filepath.replace(`${config.pages}`, '');
28
+
29
+ const { js, dependencies } = await build(filepath, config);
30
+
31
+ const depender = {
32
+ type: 'page',
33
+ path: filepath,
34
+ dependencies: dependencies
35
+ }
36
+
37
+ try {
38
+ // Create the dependency tree for this page
39
+ // (This dep tree includes components that are children and nested children)
40
+ await handleDependencies(depender, _cayo);
41
+
42
+ // TODO: configure output path base in internal cayoConfig?
43
+ let outputPath = path.resolve(
44
+ config.cayoPath,
45
+ `./__cayo/pages/${filename.replace('.svelte', '.svelte.js')}`
46
+ );
47
+ await fs.outputFile(outputPath, js.code);
48
+
49
+ const page = new Page(js.code, template, filepath, outputPath, dependencies, config);
50
+ _cayo.pages.set(filepath, page);
51
+
52
+ return page;
53
+
54
+ } catch (err) {
55
+ throw new Error(`Compiling page: ${filename}\n`, {cause: err});
56
+ }
57
+ }
58
+
59
+ async function getPagePaths(pagesPath) {
60
+ return await fg([path.resolve(pagesPath, './**/*.svelte')]);
61
+ }
@@ -0,0 +1,24 @@
1
+ import path from 'path';
2
+ import fs from 'fs-extra';
3
+ import { build } from '../bundle.js';
4
+ import { Component } from '../component.js';
5
+ import { writeTemplateCSS } from '../files.js';
6
+
7
+ export async function compileTemplate(_cayo) {
8
+ const { template: templatePath, templateName } = _cayo.config;
9
+ let filename = `${templateName}.svelte`;
10
+ try {
11
+ const { js, dependencies } = await build(templatePath, _cayo.config, 'template');
12
+ let outputPath = path.resolve(_cayo.config.cayoPath, `./__cayo/template.js`);
13
+ await fs.outputFile(outputPath, js.code);
14
+
15
+ const Template = new Component('template', { js }, templatePath, outputPath, dependencies, _cayo.config);
16
+ _cayo.template = await Template.render(_cayo, { load: true });
17
+ await writeTemplateCSS(_cayo.template.css, _cayo);
18
+
19
+ return Template;
20
+
21
+ } catch (err) {
22
+ throw new Error(`Compiling template: ${filename}`, {cause: err});
23
+ }
24
+ }
@@ -0,0 +1,62 @@
1
+ import { hash } from './utils.js';
2
+
3
+ export class Component {
4
+ constructor(
5
+ name,
6
+ output = { js: { code: '' }, css: { code: '' } },
7
+ sourcePath,
8
+ modulePath,
9
+ dependencies,
10
+ config
11
+ ) {
12
+ this._config = config;
13
+ this._name = name;
14
+ this._dependencies = dependencies || new Set();
15
+ this._source = sourcePath;
16
+ this._module = null;
17
+ this._modulePath = modulePath;
18
+ this._output = output;
19
+ }
20
+
21
+ async load() {
22
+ this._module = (await import(`${this._modulePath}?v=${hash()}`)).default;
23
+ return this._module;
24
+ }
25
+
26
+ async render(_cayo, options = {}) {
27
+ const { load = false } = options;
28
+ if (load) await this.load();
29
+
30
+ try {
31
+ this._result = this._module.render();
32
+ } catch (err) {
33
+ throw new Error(`Could not render component: ${this._name} at ${this._source}`, { cause: err })
34
+ }
35
+ return this._result;
36
+ }
37
+
38
+ get name() {
39
+ return this._name;
40
+ }
41
+
42
+ get dependencies() {
43
+ return this._dependencies;
44
+ }
45
+
46
+ set dependencies(deps) {
47
+ this._dependencies = deps;
48
+ }
49
+
50
+ get output() {
51
+ return this._output;
52
+ }
53
+
54
+ get source() {
55
+ return this._source;
56
+ }
57
+
58
+ get result() {
59
+ return this._result;
60
+ }
61
+
62
+ }