cayo 0.9.10 → 0.9.11
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.
- package/README.md +504 -5
- package/cayo.js +1 -298
- package/devlog.md +177 -0
- package/dist/cayo.svelte.js +80 -0
- package/dist/entry.svelte.js +16 -0
- package/dist/index.js +2 -0
- package/docs/config-reference.md +349 -0
- package/docs/how-cayo-works.md +28 -0
- package/docs/why-i-created-cayo.md +21 -0
- package/lib/cli/build.js +34 -0
- package/lib/cli/cli.js +152 -0
- package/lib/cli/dev.js +12 -0
- package/lib/cli/serve.js +25 -0
- package/lib/cli/watch.js +125 -0
- package/lib/core/bundle.js +155 -0
- package/lib/core/codegen.js +156 -0
- package/lib/core/compile/cayos.js +65 -0
- package/lib/core/compile/index.js +3 -0
- package/lib/core/compile/pages.js +61 -0
- package/lib/core/compile/template.js +24 -0
- package/lib/core/component.js +62 -0
- package/lib/core/config.js +206 -0
- package/lib/core/dependencies.js +167 -0
- package/lib/core/entry.js +24 -0
- package/lib/core/files.js +99 -0
- package/lib/core/logger.js +47 -0
- package/lib/core/page.js +59 -0
- package/lib/core/render/prerender.js +240 -0
- package/lib/core/render/renderer.js +52 -0
- package/lib/core/utils.js +60 -0
- package/package.json +21 -10
- package/scripts/build.js +60 -0
- package/src/cayo-warnings.js +37 -0
- package/src/cayo.svelte +36 -0
- package/src/entry.svelte +6 -0
- package/template/cayo.config.js +3 -0
- package/template/package.json +7 -0
- package/template/public/vite.svg +1 -0
- package/{tests/basic cases (old)/src/__index.svelte → template/src/__template.svelte} +3 -6
- package/template/src/components/counter.cayo.svelte +27 -0
- package/template/src/index.js +4 -0
- package/template/src/pages/index.svelte +15 -0
- package/template/src/style.css +13 -0
- package/lib/cli.js +0 -69
- package/lib/codegen.js +0 -79
- package/lib/components/Cayo.svelte +0 -25
- package/lib/config.js +0 -155
- package/lib/files.js +0 -84
- package/lib/prerender.js +0 -181
- package/lib/renderer.js +0 -49
- package/lib/runtime.js +0 -6
- package/lib/utils.js +0 -126
- package/lib/vite.config.js +0 -16
- package/notes.md +0 -3
- package/test/cayo.config.js +0 -35
- package/test/public/assets/cow.js +0 -1
- package/test/public/images/app-icon.png +0 -0
- package/test/src/__layout.svelte +0 -20
- package/test/src/components/Cool.cayo.svelte +0 -5
- package/test/src/components/Some.svelte +0 -1
- package/test/src/components/Test.cayo.svelte +0 -5
- package/test/src/index.js +0 -17
- package/test/src/main2.js +0 -1
- package/test/src/pages/hey.svelte +0 -8
- package/test/src/pages/howdy.svelte +0 -11
- package/test/src/pages/index.svelte +0 -38
- package/test/src/pages/some/page.svelte +0 -2
- package/tests/asset-dir/cayo.config.js +0 -38
- package/tests/asset-dir/package-lock.json +0 -1435
- package/tests/asset-dir/package.json +0 -19
- package/tests/asset-dir/public/images/app-icon.png +0 -0
- package/tests/asset-dir/src/__layout.svelte +0 -20
- package/tests/asset-dir/src/components/CayoExample.svelte +0 -5
- package/tests/asset-dir/src/components/Some.cayo.svelte +0 -6
- package/tests/asset-dir/src/index.js +0 -5
- package/tests/asset-dir/src/pages/index.svelte +0 -19
- package/tests/base-path/cayo.config.js +0 -36
- package/tests/base-path/package-lock.json +0 -1435
- package/tests/base-path/package.json +0 -19
- package/tests/base-path/public/assets/cow.js +0 -1
- package/tests/base-path/public/images/app-icon.png +0 -0
- package/tests/base-path/src/__layout.svelte +0 -20
- package/tests/base-path/src/components/CayoExample.svelte +0 -5
- package/tests/base-path/src/components/Some.cayo.svelte +0 -6
- package/tests/base-path/src/index.js +0 -5
- package/tests/base-path/src/pages/howdy.svelte +0 -12
- package/tests/base-path/src/pages/index.svelte +0 -20
- package/tests/basic/notcayo.config.js +0 -35
- package/tests/basic/package-lock.json +0 -1435
- package/tests/basic/package.json +0 -19
- package/tests/basic/public/assets/cow.js +0 -1
- package/tests/basic/public/images/app-icon.png +0 -0
- package/tests/basic/src/__layout.svelte +0 -20
- package/tests/basic/src/components/Cool.cayo.svelte +0 -4
- package/tests/basic/src/components/Some.svelte +0 -1
- package/tests/basic/src/index.js +0 -5
- package/tests/basic/src/main2.js +0 -1
- package/tests/basic/src/pages/hey.svelte +0 -8
- package/tests/basic/src/pages/howdy.svelte +0 -11
- package/tests/basic/src/pages/index.svelte +0 -33
- package/tests/basic/src/pages/some/some.svelte +0 -2
- package/tests/basic cases (old)/src/components/Cool.cayo.svelte +0 -4
- package/tests/basic cases (old)/src/components/Some.svelte +0 -1
- package/tests/basic cases (old)/src/components/dir/Cool.cayo.svelte +0 -4
- package/tests/basic cases (old)/src/main.js +0 -1
- package/tests/basic cases (old)/src/main2.js +0 -1
- package/tests/basic cases (old)/src/pages/hey.svelte +0 -2
- package/tests/basic cases (old)/src/pages/howdy.svelte +0 -11
- package/tests/basic cases (old)/src/pages/index.svelte +0 -27
- package/tests/nested-pages/cayo.config.js +0 -35
- package/tests/nested-pages/package-lock.json +0 -1435
- package/tests/nested-pages/package.json +0 -19
- package/tests/nested-pages/public/assets/cow.js +0 -1
- package/tests/nested-pages/public/images/app-icon.png +0 -0
- package/tests/nested-pages/src/__layout.svelte +0 -20
- package/tests/nested-pages/src/components/Cool.cayo.svelte +0 -4
- package/tests/nested-pages/src/index.js +0 -5
- package/tests/nested-pages/src/main2.js +0 -1
- package/tests/nested-pages/src/pages/index.svelte +0 -18
- package/tests/nested-pages/src/pages/some/other/page.svelte +0 -7
- package/tests/nested-pages/src/pages/some/page.svelte +0 -6
package/lib/cli.js
DELETED
|
@@ -1,69 +0,0 @@
|
|
|
1
|
-
import { loadConfig } from './config.js';
|
|
2
|
-
import yargs from 'yargs-parser';
|
|
3
|
-
import { devServer } from './dev.js';
|
|
4
|
-
import { build } from './build.js';
|
|
5
|
-
import fs from 'fs-extra';
|
|
6
|
-
|
|
7
|
-
// TODO: move this elsewhere
|
|
8
|
-
if (!fs.existsSync(dotPath)) {
|
|
9
|
-
await fs.mkdir(dotPath)
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
// Load config
|
|
13
|
-
|
|
14
|
-
// Handle arguments
|
|
15
|
-
function resolveArgs(argv) {
|
|
16
|
-
|
|
17
|
-
const cmd = argv._[2]
|
|
18
|
-
const options = {
|
|
19
|
-
//TODO: support options from command line
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
switch (cmd) {
|
|
23
|
-
case 'dev':
|
|
24
|
-
return { cmd: 'dev', options };
|
|
25
|
-
case 'build':
|
|
26
|
-
return { cmd: 'build', options };
|
|
27
|
-
default:
|
|
28
|
-
return { cmd: 'help', options };
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
function printHelp() {
|
|
33
|
-
// TODO: help info
|
|
34
|
-
console.log('help');
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
function run(command) {
|
|
38
|
-
const { cmd, options } = command;
|
|
39
|
-
try {
|
|
40
|
-
// const { projectRoot, configPath } = options;
|
|
41
|
-
const config = await loadConfig(options);
|
|
42
|
-
|
|
43
|
-
// TODO: actually run command now
|
|
44
|
-
} catch (err) {
|
|
45
|
-
console.error(err);
|
|
46
|
-
process.exit(1);
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
// Run
|
|
51
|
-
export async function cli(args) {
|
|
52
|
-
const argv = yargs(args);
|
|
53
|
-
const command = resolveArgs(argv);
|
|
54
|
-
// TODO: do something with options
|
|
55
|
-
|
|
56
|
-
switch(command.cmd) {
|
|
57
|
-
case 'dev':
|
|
58
|
-
// run server
|
|
59
|
-
devServer();
|
|
60
|
-
break;
|
|
61
|
-
case 'build':
|
|
62
|
-
// run build
|
|
63
|
-
build();
|
|
64
|
-
break;
|
|
65
|
-
case 'help':
|
|
66
|
-
default:
|
|
67
|
-
printHelp();
|
|
68
|
-
}
|
|
69
|
-
}
|
package/lib/codegen.js
DELETED
|
@@ -1,79 +0,0 @@
|
|
|
1
|
-
import path from 'path';
|
|
2
|
-
|
|
3
|
-
// Generate runtime helper that finds and parses a component instance's prop data
|
|
4
|
-
export function generateGetProps() {
|
|
5
|
-
return (
|
|
6
|
-
`
|
|
7
|
-
function getProps(cayoId) {
|
|
8
|
-
const componentElement = document.querySelector(\`[data-cayo-id="\${cayoId}"]\`);
|
|
9
|
-
const json = componentElement.dataset.cayoProps;
|
|
10
|
-
return JSON.parse(json);
|
|
11
|
-
}
|
|
12
|
-
`
|
|
13
|
-
);
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
export function generateCayoRuntime(components, config) {
|
|
17
|
-
let code = '';
|
|
18
|
-
let instances = '';
|
|
19
|
-
|
|
20
|
-
if (Object.keys(components).length !== 0) {
|
|
21
|
-
// TODO: add this path to config (internal only)
|
|
22
|
-
// const componentPath = path.resolve(config.cayoPath, './__cayo/components');
|
|
23
|
-
const componentPath = '/__cayo/components';
|
|
24
|
-
Object.entries(components).forEach(([name, ids]) => {
|
|
25
|
-
// Add component dependency import
|
|
26
|
-
code += `import { ${name} } from '${componentPath}/${name}.js';\n`;
|
|
27
|
-
// Generate component instances
|
|
28
|
-
ids.forEach(id => {
|
|
29
|
-
instances += generateComponentInstance(id, name)
|
|
30
|
-
});
|
|
31
|
-
});
|
|
32
|
-
|
|
33
|
-
// Add getProps (used by component instances)
|
|
34
|
-
code += generateGetProps();
|
|
35
|
-
} else {
|
|
36
|
-
instances += ` // No cayo component instances found in page HTML`;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
// Add main render, which runs the component instantiations
|
|
40
|
-
code += generateRender(instances);
|
|
41
|
-
|
|
42
|
-
return { code };
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
function generateRender(contents) {
|
|
46
|
-
return (
|
|
47
|
-
`
|
|
48
|
-
export default function render(cb) {
|
|
49
|
-
var target = function (node) { return node; }
|
|
50
|
-
if (cb) target = cb;
|
|
51
|
-
${contents}
|
|
52
|
-
}
|
|
53
|
-
`
|
|
54
|
-
);
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
// Generate the code to wrap component instances in an event listener wrapper
|
|
58
|
-
export function generateComponentInstanceWrapper(contents) {
|
|
59
|
-
return (
|
|
60
|
-
`
|
|
61
|
-
document.addEventListener('DOMContentLoaded', function() {
|
|
62
|
-
${contents}
|
|
63
|
-
});
|
|
64
|
-
`
|
|
65
|
-
);
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
// Generate the code for a component instance
|
|
69
|
-
export function generateComponentInstance(cayoId, componentName) {
|
|
70
|
-
return (
|
|
71
|
-
`
|
|
72
|
-
new ${componentName}({
|
|
73
|
-
target: target(document.querySelector('[data-cayo-id="${cayoId}"]')),
|
|
74
|
-
hydrate: true,
|
|
75
|
-
props: getProps('${cayoId}'),
|
|
76
|
-
});
|
|
77
|
-
`
|
|
78
|
-
);
|
|
79
|
-
}
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
<script>
|
|
2
|
-
import * as crypto from 'crypto';
|
|
3
|
-
// import { Boundary } from '@crownframework/svelte-error-boundary';
|
|
4
|
-
|
|
5
|
-
export let name;
|
|
6
|
-
|
|
7
|
-
// TODO: Consider error handling for required stuff
|
|
8
|
-
// if (!name) throw new Error('No name for component');
|
|
9
|
-
// try {
|
|
10
|
-
// if (!name) throw new Error(`\x1b[31mCayo Component: 'name' prop is required and can't be an empty string`);
|
|
11
|
-
// } catch (err) {
|
|
12
|
-
// new Error(err);
|
|
13
|
-
// }
|
|
14
|
-
|
|
15
|
-
function hash() {
|
|
16
|
-
return crypto.randomBytes(3).toString('hex');
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
const json = JSON.stringify($$restProps);
|
|
20
|
-
</script>
|
|
21
|
-
|
|
22
|
-
<div data-cayo-id={name ? `${name}-${hash()}` : ''} data-cayo-props={json}>
|
|
23
|
-
<slot/>
|
|
24
|
-
</div>
|
|
25
|
-
|
package/lib/config.js
DELETED
|
@@ -1,155 +0,0 @@
|
|
|
1
|
-
import path from 'path';
|
|
2
|
-
import fs from 'fs-extra';
|
|
3
|
-
import { z } from 'zod';
|
|
4
|
-
import { normalizePath } from './utils.js';
|
|
5
|
-
import { default as viteConfig } from './vite.config.js';
|
|
6
|
-
import chalk from 'chalk';
|
|
7
|
-
import merge from 'deepmerge';
|
|
8
|
-
|
|
9
|
-
async function validateConfig(userConfig, base) {
|
|
10
|
-
const ConfigSchema = z.object({
|
|
11
|
-
projectRoot: z
|
|
12
|
-
.string()
|
|
13
|
-
.optional()
|
|
14
|
-
.default('.')
|
|
15
|
-
.transform(val => normalizePath(base, val)),
|
|
16
|
-
src: z
|
|
17
|
-
.string()
|
|
18
|
-
.optional()
|
|
19
|
-
.default('./src')
|
|
20
|
-
.transform(val => normalizePath(base, val)),
|
|
21
|
-
pages: z
|
|
22
|
-
.string()
|
|
23
|
-
.optional()
|
|
24
|
-
.default('./src/pages')
|
|
25
|
-
.transform(val => normalizePath(base, val)),
|
|
26
|
-
publicDir: z
|
|
27
|
-
.string()
|
|
28
|
-
.optional()
|
|
29
|
-
.default('./public')
|
|
30
|
-
.transform(val => normalizePath(base, val)),
|
|
31
|
-
base: z
|
|
32
|
-
.string()
|
|
33
|
-
.optional(),
|
|
34
|
-
build: z
|
|
35
|
-
.object({
|
|
36
|
-
outDir: z
|
|
37
|
-
.string()
|
|
38
|
-
.optional()
|
|
39
|
-
.default('./dist')
|
|
40
|
-
.transform(val => normalizePath(base, val)),
|
|
41
|
-
assetsDir: z
|
|
42
|
-
.string()
|
|
43
|
-
.optional()
|
|
44
|
-
.default('assets'),
|
|
45
|
-
// .transform(val => normalizePath(base, val)),
|
|
46
|
-
legacy: z.
|
|
47
|
-
boolean()
|
|
48
|
-
.optional()
|
|
49
|
-
.default(false),
|
|
50
|
-
})
|
|
51
|
-
.optional()
|
|
52
|
-
.default({}),
|
|
53
|
-
css: z
|
|
54
|
-
.object({
|
|
55
|
-
internal: z
|
|
56
|
-
.boolean()
|
|
57
|
-
.optional()
|
|
58
|
-
.default(false),
|
|
59
|
-
})
|
|
60
|
-
.optional()
|
|
61
|
-
.default({}),
|
|
62
|
-
viteConfig: z
|
|
63
|
-
.any({}),
|
|
64
|
-
// .default(viteConfig),
|
|
65
|
-
cayoPath: z
|
|
66
|
-
.string()
|
|
67
|
-
.optional()
|
|
68
|
-
.default('.cayo/')
|
|
69
|
-
.transform(val => normalizePath(base, val)),
|
|
70
|
-
cayoComponentInfix: z
|
|
71
|
-
.string()
|
|
72
|
-
.optional()
|
|
73
|
-
.default('cayo'),
|
|
74
|
-
templateFileName: z
|
|
75
|
-
.string()
|
|
76
|
-
.default('__layout'),
|
|
77
|
-
mode: z
|
|
78
|
-
.string()
|
|
79
|
-
.optional()
|
|
80
|
-
.default('development'),
|
|
81
|
-
});
|
|
82
|
-
|
|
83
|
-
return await ConfigSchema.parseAsync(userConfig);
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
export function checkConfigPaths(config, logger) {
|
|
87
|
-
let errorLogged = false;
|
|
88
|
-
const log = (option, value) => {
|
|
89
|
-
logger.warn(
|
|
90
|
-
chalk.red(`Config Error: ${option}: '${value}' does not exist`),
|
|
91
|
-
{ timestamp: true, clear: false, }
|
|
92
|
-
);
|
|
93
|
-
errorLogged = true;
|
|
94
|
-
}
|
|
95
|
-
if (!fs.existsSync(config.projectRoot))
|
|
96
|
-
log('config.projectRoot', config.projectRoot);
|
|
97
|
-
if (!fs.existsSync(path.resolve(config.projectRoot, config.src)))
|
|
98
|
-
log('config.src', config.projectRoot);
|
|
99
|
-
if (!fs.existsSync(path.resolve(config.projectRoot, config.pages)))
|
|
100
|
-
log('config.pages', config.pages);
|
|
101
|
-
if (!fs.existsSync(path.resolve(config.projectRoot, config.publicDir)))
|
|
102
|
-
log('config.publicDir', config.publicDir);
|
|
103
|
-
if (!fs.existsSync(path.resolve(config.src, `${config.templateFileName}.svelte`)))
|
|
104
|
-
log('config.templateFileName', `${config.templateFileName}(.svelte)`);
|
|
105
|
-
if (!fs.existsSync(path.resolve(config.projectRoot, config.publicDir)))
|
|
106
|
-
log('config.publicDir', config.publicDir);
|
|
107
|
-
|
|
108
|
-
if(errorLogged) throw new Error('Config Error: fix the issues above in your config file');
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
export async function loadConfig(options) {
|
|
112
|
-
const configFileName = 'cayo.config.js';
|
|
113
|
-
|
|
114
|
-
// Use options passed to the CLI for projectRoot and configPath
|
|
115
|
-
const root = options.projectRoot
|
|
116
|
-
? path.resolve(options.projectRoot)
|
|
117
|
-
: process.cwd();
|
|
118
|
-
|
|
119
|
-
const configPath = options.configPath
|
|
120
|
-
? path.resolve(root, options.configPath)
|
|
121
|
-
: path.resolve(root, `./${configFileName}`);
|
|
122
|
-
|
|
123
|
-
// Load config from user config file
|
|
124
|
-
let userConfig = { projectRoot: root, mode: options.mode };
|
|
125
|
-
if (fs.existsSync(configPath)) {
|
|
126
|
-
userConfig = {
|
|
127
|
-
...(await import(configPath)).default,
|
|
128
|
-
...userConfig,
|
|
129
|
-
};
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
const config = await validateConfig(userConfig, root);
|
|
133
|
-
if (config.viteConfig) {
|
|
134
|
-
const mergedViteConfig = merge(viteConfig, config.viteConfig, { arrayMerge: combineMerge });
|
|
135
|
-
config.viteConfig = mergedViteConfig;
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
return config;
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
// Credit: https://github.com/TehShrike/deepmerge#arraymerge-example-combine-arrays
|
|
142
|
-
function combineMerge(target, source, options) {
|
|
143
|
-
const destination = target.slice()
|
|
144
|
-
|
|
145
|
-
source.forEach((item, index) => {
|
|
146
|
-
if (typeof destination[index] === 'undefined') {
|
|
147
|
-
destination[index] = options.cloneUnlessOtherwiseSpecified(item, options)
|
|
148
|
-
} else if (options.isMergeableObject(item)) {
|
|
149
|
-
destination[index] = merge(target[index], item, options)
|
|
150
|
-
} else if (target.indexOf(item) === -1) {
|
|
151
|
-
destination.push(item)
|
|
152
|
-
}
|
|
153
|
-
})
|
|
154
|
-
return destination
|
|
155
|
-
}
|
package/lib/files.js
DELETED
|
@@ -1,84 +0,0 @@
|
|
|
1
|
-
import fs from 'fs-extra';
|
|
2
|
-
import path from 'path';
|
|
3
|
-
import chalk from 'chalk';
|
|
4
|
-
|
|
5
|
-
// Write file content for a page
|
|
6
|
-
export async function writePageFiles(page, outDir, logger, config) {
|
|
7
|
-
const { html, css, js, entry } = page;
|
|
8
|
-
const htmlPath = page.urlPath === '/' ? 'index.html' : `${page.filePath}/index.html`;
|
|
9
|
-
// Write HTML
|
|
10
|
-
await fs.outputFile(path.resolve(outDir, `${htmlPath}`), html)
|
|
11
|
-
.then(() => logger.info(
|
|
12
|
-
chalk.green('page build ') + chalk.dim(`${page.filePath}`),
|
|
13
|
-
{ timestamp: true })
|
|
14
|
-
);
|
|
15
|
-
// Write CSS
|
|
16
|
-
if (css.code !== '' && !config.css.internal) {
|
|
17
|
-
const cssPath = page.urlPath === '/' ? 'index.css' : `${page.filePath}/index.css`;
|
|
18
|
-
await fs.outputFile(path.resolve(outDir, cssPath), css)
|
|
19
|
-
.then(() => logger.info(
|
|
20
|
-
chalk.green('css build ') + chalk.dim(`${page.filePath}`),
|
|
21
|
-
{ timestamp: true })
|
|
22
|
-
);
|
|
23
|
-
}
|
|
24
|
-
// Write Cayo runtime JS
|
|
25
|
-
if (js.code !== '') {
|
|
26
|
-
let jsPath = page.urlPath === '/' ? 'cayo-runtime.js' : `${page.filePath}/cayo-runtime.js`;
|
|
27
|
-
let content = '';
|
|
28
|
-
content += js.code;
|
|
29
|
-
await fs.outputFile(path.resolve(outDir, jsPath), content)
|
|
30
|
-
.then(() => logger.info(
|
|
31
|
-
chalk.green('cayo runtime build ') + chalk.dim(`${page.filePath}`),
|
|
32
|
-
{ timestamp: true })
|
|
33
|
-
);
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
// Copy user entry JS
|
|
37
|
-
if (entry.path !== '') {
|
|
38
|
-
let entryRelativePath = page.urlPath === '/' ? `./index.js` : `${page.filePath}${path.sep}index.js`;
|
|
39
|
-
await fs.copy(entry.path, path.resolve(outDir, entryRelativePath))
|
|
40
|
-
.then(() => logger.info(
|
|
41
|
-
chalk.green('entry build ') + chalk.dim(`${page.filePath}`),
|
|
42
|
-
{ timestamp: true })
|
|
43
|
-
).catch(err => console.error(err));
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
export async function writeTemplateCSS(css, outDir, logger, config) {
|
|
48
|
-
if (css.code !== '' && !config.css.internal) {
|
|
49
|
-
const cssPath = `__index.css`;
|
|
50
|
-
await fs.outputFile(path.resolve(outDir, cssPath), css.code)
|
|
51
|
-
.then(() => logger.info(
|
|
52
|
-
chalk.green('css build ') + chalk.dim(`${config.templateFileName}`),
|
|
53
|
-
{ timestamp: true })
|
|
54
|
-
);
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
export async function writeComponentFile(name, modulePath, outDir, logger) {
|
|
59
|
-
let content = `export { default as ${name} } from '${modulePath}';\n`;
|
|
60
|
-
await fs.outputFile(path.resolve(outDir, `./__cayo/components/${name}.js`), content)
|
|
61
|
-
.then(() => logger.info(
|
|
62
|
-
chalk.green('component dep ') + chalk.dim(`${name}`),
|
|
63
|
-
{ timestamp: true })
|
|
64
|
-
);
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
export function cleanCayoPath(cayoPath) {
|
|
68
|
-
fs.removeSync(cayoPath);
|
|
69
|
-
fs.ensureDirSync(cayoPath);
|
|
70
|
-
// if (!fs.existsSync(cayoPath)) {
|
|
71
|
-
// try {
|
|
72
|
-
// fs.mkdirSync(cayoPath)
|
|
73
|
-
// } catch (err) {
|
|
74
|
-
// console.error(err);
|
|
75
|
-
// }
|
|
76
|
-
// } else {
|
|
77
|
-
// try {
|
|
78
|
-
// fs.removeSync(cayoPath)
|
|
79
|
-
// fs.mkdirSync(cayoPath);
|
|
80
|
-
// } catch (err) {
|
|
81
|
-
// console.error(err);
|
|
82
|
-
// }
|
|
83
|
-
// }
|
|
84
|
-
}
|
package/lib/prerender.js
DELETED
|
@@ -1,181 +0,0 @@
|
|
|
1
|
-
import fs from 'fs-extra';
|
|
2
|
-
import path from 'path';
|
|
3
|
-
import { JSDOM } from 'jsdom';
|
|
4
|
-
import { Renderer } from './renderer.js';
|
|
5
|
-
import { generateCayoRuntime } from './codegen.js';
|
|
6
|
-
import chalk from 'chalk';
|
|
7
|
-
|
|
8
|
-
export function prerender(Template, pages, componentModules, config, logger) {
|
|
9
|
-
const template = Template.render();
|
|
10
|
-
const renderer = new Renderer(template);
|
|
11
|
-
const componentList = new Set();
|
|
12
|
-
|
|
13
|
-
// const prerendered = {};
|
|
14
|
-
// Render page, parse html, and save its deps
|
|
15
|
-
const prerendered = Object.entries(pages).reduce(
|
|
16
|
-
(prerendered, [pathname, page]) => {
|
|
17
|
-
// Render page
|
|
18
|
-
const content = renderer.render(page, config);
|
|
19
|
-
// Postprocess the content, get deps and inject dep references
|
|
20
|
-
const { html, css, js, entry, components } = processPage(content, page, Object.keys(componentModules), config, logger);
|
|
21
|
-
prerendered[pathname] = {
|
|
22
|
-
html,
|
|
23
|
-
css,
|
|
24
|
-
js,
|
|
25
|
-
entry,
|
|
26
|
-
components,
|
|
27
|
-
...page,
|
|
28
|
-
}
|
|
29
|
-
Object.keys(components).forEach(component => componentList.add(component))
|
|
30
|
-
return prerendered;
|
|
31
|
-
}, {}
|
|
32
|
-
);
|
|
33
|
-
|
|
34
|
-
return {
|
|
35
|
-
prerendered,
|
|
36
|
-
componentList,
|
|
37
|
-
template,
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
// Derive JS dependencies from the prerendered html
|
|
42
|
-
export function processPage(content, page, componentNames, config, logger) {
|
|
43
|
-
const tags = findDocumentTags(content.html);
|
|
44
|
-
const dom = new JSDOM(content.html);
|
|
45
|
-
const { document } = dom.window;
|
|
46
|
-
|
|
47
|
-
// Get component instance ids
|
|
48
|
-
let cayoIds = [];
|
|
49
|
-
document.querySelectorAll('[data-cayo-id]').forEach((el) => {
|
|
50
|
-
if (el.dataset.cayoId !== '') {
|
|
51
|
-
cayoIds.push(el.dataset.cayoId);
|
|
52
|
-
} else {
|
|
53
|
-
logger.info(
|
|
54
|
-
chalk.red(`Cayo component instance without a name found`) + chalk.dim(` ${page.filePath}`),
|
|
55
|
-
{ timestamp: true, clear: true, }
|
|
56
|
-
);
|
|
57
|
-
}
|
|
58
|
-
});
|
|
59
|
-
|
|
60
|
-
// Get component list
|
|
61
|
-
// TODO: make this regex allow '-' character, before the last one, to be part of the component name?
|
|
62
|
-
const componentNameRegex = /(?<name>\w+)-/; // Foo-{hash}
|
|
63
|
-
const components = cayoIds.reduce((components, id) => {
|
|
64
|
-
let name = id.match(componentNameRegex).groups.name;
|
|
65
|
-
if (!componentNames.includes(name)) {
|
|
66
|
-
logger.warn(
|
|
67
|
-
chalk.red(
|
|
68
|
-
`Cayo component with name '${name}' does not exist but is trying to be rendered`
|
|
69
|
-
) + chalk.dim(` ${page.filePath}`),
|
|
70
|
-
{ timestamp: true, clear: true, }
|
|
71
|
-
);
|
|
72
|
-
return components;
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
if (!components[name]) {
|
|
76
|
-
components[name] = [id]
|
|
77
|
-
} else {
|
|
78
|
-
components[name].push(id);
|
|
79
|
-
}
|
|
80
|
-
return components;
|
|
81
|
-
}, {});
|
|
82
|
-
|
|
83
|
-
// Get user-specified entry file name
|
|
84
|
-
// TODO: can just be querySelector? should only be one instance. maybe warn if more than one.
|
|
85
|
-
const entryScripts = document.querySelectorAll('script[data-cayo-entry]');
|
|
86
|
-
let userEntryFile = entryScripts.length !== 0 ? entryScripts[0].src : '';
|
|
87
|
-
// Remove user-specified entry file placeholder
|
|
88
|
-
if (userEntryFile) {
|
|
89
|
-
entryScripts.forEach((script) => {
|
|
90
|
-
script.remove();
|
|
91
|
-
});
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
// Build generated entry file contents
|
|
95
|
-
let js = { code: '' };
|
|
96
|
-
let entry = {
|
|
97
|
-
path: '',
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
if (!userEntryFile) {
|
|
101
|
-
// Remove the entry point script tag if the page doesn't need any JS
|
|
102
|
-
// This is injected by Renderer.render based on the template
|
|
103
|
-
const entryScript = document.querySelector(`script[type="module"][src="./index.js"]`);
|
|
104
|
-
if (entryScript) {
|
|
105
|
-
entryScript.remove();
|
|
106
|
-
} else {
|
|
107
|
-
logger.info(
|
|
108
|
-
chalk.bgRed.white(`No entry placeholder in template file.`) + chalk.dim(` Cayo components will not render.`),
|
|
109
|
-
{ timestamp: true }
|
|
110
|
-
);
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
if (userEntryFile[0] === '/') {
|
|
115
|
-
userEntryFile = userEntryFile.substring(1);
|
|
116
|
-
} else if (userEntryFile && userEntryFile[0] !== '/') {
|
|
117
|
-
logger.warn(
|
|
118
|
-
chalk.red(
|
|
119
|
-
`Entry file path '${userEntryFile}' requires a leading slash and to be relative to src`
|
|
120
|
-
) + chalk.dim(` ${page.filePath}`),
|
|
121
|
-
{ timestamp: true, clear: true, }
|
|
122
|
-
);
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
if (userEntryFile) {
|
|
126
|
-
const entryFilePath = path.resolve(
|
|
127
|
-
config.src,
|
|
128
|
-
userEntryFile
|
|
129
|
-
);
|
|
130
|
-
|
|
131
|
-
if (!fs.pathExistsSync(entryFilePath)) {
|
|
132
|
-
console.error(`Can't read entry file ${userEntryFile} in ${page.modulePath}`);
|
|
133
|
-
} else {
|
|
134
|
-
entry.path = entryFilePath;
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
js = generateCayoRuntime(components, config);
|
|
139
|
-
|
|
140
|
-
// Construct the correct HTML string based on the document tags
|
|
141
|
-
// that were rendered from the source (jsdom wraps the source HTML in a document,
|
|
142
|
-
// which always includes `html`, `head`, and `body`, even if the source doesn't)
|
|
143
|
-
let processedHTML = '';
|
|
144
|
-
if (tags.html) {
|
|
145
|
-
processedHTML = dom.window.document.documentElement.outerHTML;
|
|
146
|
-
|
|
147
|
-
} else {
|
|
148
|
-
if (tags.head) {
|
|
149
|
-
processedHTML += dom.window.document.head.outerHTML;
|
|
150
|
-
} else {
|
|
151
|
-
processedHTML += dom.window.document.head.innerHTML;
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
if (tags.body) {
|
|
155
|
-
processedHTML += dom.window.document.body.outerHTML;
|
|
156
|
-
} else {
|
|
157
|
-
processedHTML += dom.window.document.body.innerHTML;
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
return {
|
|
162
|
-
html: processedHTML,
|
|
163
|
-
css: content.css.code,
|
|
164
|
-
js,
|
|
165
|
-
components,
|
|
166
|
-
entry,
|
|
167
|
-
};
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
function findDocumentTags(source) {
|
|
172
|
-
const head = source.match(/\<head[\s\S]*\>(?<innerHTML>[\s\S]*)\<\/head\>/g);
|
|
173
|
-
const body = source.match(/\<body[\s\S]*\>(?<innerHTML>[\s\S]*)\<\/body\>/g);
|
|
174
|
-
const html = source.match(/\<html[\s\S]*\>(?<innerHTML>[\s\S]*)\<\/html\>/g);
|
|
175
|
-
|
|
176
|
-
return {
|
|
177
|
-
head: head === null ? false : true,
|
|
178
|
-
body: body === null ? false : true,
|
|
179
|
-
html: html === null ? false : true,
|
|
180
|
-
};
|
|
181
|
-
}
|
package/lib/renderer.js
DELETED
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
import path from 'path';
|
|
2
|
-
|
|
3
|
-
export class Renderer {
|
|
4
|
-
|
|
5
|
-
constructor(template) {
|
|
6
|
-
this.template = template;
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
render(page, config) {
|
|
10
|
-
const { css: cssOptions } = config;
|
|
11
|
-
|
|
12
|
-
const { Component } = page;
|
|
13
|
-
const { html, css, head } = Component.render();
|
|
14
|
-
|
|
15
|
-
// TODO: template function for page title
|
|
16
|
-
let title = page.meta.title ? `${page.meta.title}` : 'Cayo';
|
|
17
|
-
|
|
18
|
-
let cssTag = '';
|
|
19
|
-
if (cssOptions.internal === false) {
|
|
20
|
-
if (this.template.css.code !== '') {
|
|
21
|
-
cssTag += `<link rel="stylesheet" href="/__index.css">\n`;
|
|
22
|
-
}
|
|
23
|
-
cssTag += `<link rel="stylesheet" href="./index.css">`;
|
|
24
|
-
} else {
|
|
25
|
-
if (this.template.css.code !== '') {
|
|
26
|
-
cssTag += `<style>/* Template CSS */${this.template.css.code}</style>\n`;
|
|
27
|
-
}
|
|
28
|
-
cssTag += `<style>${css.code}</style>`;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
// NOTE: Q: why the `() => str` for 2nd replacement arg?
|
|
32
|
-
// A: In case there's dollar signs in that there string
|
|
33
|
-
// https://stackoverflow.com/questions/9423722/string-replace-weird-behavior-when-using-dollar-sign-as-replacement
|
|
34
|
-
|
|
35
|
-
return {
|
|
36
|
-
html: this.template.html
|
|
37
|
-
// Ignore placeholders wrapped in HTML comments
|
|
38
|
-
.replace(/<!--[^]*\%cayo\.\w+\%[^]*-->/g, '')
|
|
39
|
-
// Replace placeholders in template
|
|
40
|
-
.replace('%cayo.title%', () => !head.includes('<title>') ? `<title>${title}</title>` : '')
|
|
41
|
-
.replace('%cayo.head%', () => head)
|
|
42
|
-
.replace('%cayo.body%', () => html)
|
|
43
|
-
.replace('%cayo.css%', () => cssTag)
|
|
44
|
-
.replace('%cayo.script%', () => `<script type="module" src="./index.js"></script>`)
|
|
45
|
-
,
|
|
46
|
-
css: css,
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
}
|