@primate/angular 0.1.4 → 0.2.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.
- package/package.json +21 -11
- package/src/private/build/client.js +11 -0
- package/src/private/build/compile.js +12 -0
- package/src/private/build/index.js +17 -1
- package/src/private/build/publish.js +27 -0
- package/src/private/build/server.js +2 -11
- package/src/private/client/create-root-client.js +24 -0
- package/src/private/client/create-root.js +24 -0
- package/src/private/client/expose.js +9 -0
- package/src/private/client/index.js +11 -0
- package/src/private/name.js +1 -0
- package/src/private/normalize.js +4 -0
- package/src/private/serve/index.js +22 -3
- package/src/private/serve/render.js +8 -8
- package/src/private/serve/make-root.js +0 -17
- package/src/private/serve/root-component.js +0 -9
- /package/src/private/{serve/selector.js → client/root-selector.js} +0 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@primate/angular",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Primate Angular frontend",
|
|
5
5
|
"homepage": "https://primatejs.com/modules/angular",
|
|
6
6
|
"bugs": "https://github.com/primatejs/primate/issues",
|
|
@@ -15,32 +15,42 @@
|
|
|
15
15
|
"directory": "packages/angular"
|
|
16
16
|
},
|
|
17
17
|
"dependencies": {
|
|
18
|
-
"@angular/compiler": "^18.
|
|
19
|
-
"@angular/platform-browser": "^18.
|
|
20
|
-
"@angular/platform-server": "^18.
|
|
21
|
-
"@angular/ssr": "^18.
|
|
22
|
-
"@rcompat/build": "^0.
|
|
18
|
+
"@angular/compiler": "^18.2.2",
|
|
19
|
+
"@angular/platform-browser": "^18.2.2",
|
|
20
|
+
"@angular/platform-server": "^18.2.2",
|
|
21
|
+
"@angular/ssr": "^18.2.2",
|
|
22
|
+
"@rcompat/build": "^0.6.0",
|
|
23
|
+
"@rcompat/crypto": "^0.5.0",
|
|
24
|
+
"@rcompat/fs": "^0.7.0",
|
|
23
25
|
"@rcompat/object": "^0.5.0",
|
|
24
26
|
"zone.js": "^0.14.10",
|
|
25
|
-
"@primate/frontend": "^0.16.
|
|
27
|
+
"@primate/frontend": "^0.16.4"
|
|
26
28
|
},
|
|
27
29
|
"peerDependencies": {
|
|
28
30
|
"@angular/core": "18",
|
|
29
|
-
"primate": "^0.32.
|
|
31
|
+
"primate": "^0.32.6"
|
|
30
32
|
},
|
|
31
33
|
"type": "module",
|
|
32
34
|
"imports": {
|
|
33
35
|
"#*": {
|
|
34
|
-
"
|
|
36
|
+
"livetypes": "./src/private/*.js",
|
|
35
37
|
"default": "./src/private/*.js"
|
|
36
38
|
},
|
|
37
39
|
"#build": {
|
|
38
|
-
"
|
|
40
|
+
"livetypes": "./src/private/build/index.js",
|
|
39
41
|
"default": "./src/private/build/index.js"
|
|
40
42
|
},
|
|
41
43
|
"#serve": {
|
|
42
|
-
"
|
|
44
|
+
"livetypes": "./src/private/serve/index.js",
|
|
43
45
|
"default": "./src/private/serve/index.js"
|
|
46
|
+
},
|
|
47
|
+
"#client": {
|
|
48
|
+
"livetypes": "./src/private/client/index.js",
|
|
49
|
+
"default": "./src/private/client/index.js"
|
|
50
|
+
},
|
|
51
|
+
"#client/*": {
|
|
52
|
+
"livetypes": "./src/private/client/*.js",
|
|
53
|
+
"default": "./src/private/client/*.js"
|
|
44
54
|
}
|
|
45
55
|
},
|
|
46
56
|
"exports": {
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import normalize from "#normalize";
|
|
2
|
+
|
|
3
|
+
export default async (app, component) => {
|
|
4
|
+
const location = app.get("location");
|
|
5
|
+
const source = app.runpath(location.components);
|
|
6
|
+
const { path } = component.debase(source, "/");
|
|
7
|
+
|
|
8
|
+
const code = `export { default as ${await normalize(path)} } from
|
|
9
|
+
"./${location.components}/${path}";`;
|
|
10
|
+
app.build.export(code);
|
|
11
|
+
};
|
|
@@ -1,5 +1,17 @@
|
|
|
1
|
+
import create_root from "#client/create-root-client";
|
|
2
|
+
import expose from "#client/expose";
|
|
3
|
+
import name from "#name";
|
|
4
|
+
import client from "./client.js";
|
|
5
|
+
import publish from "./publish.js";
|
|
1
6
|
import server from "./server.js";
|
|
2
7
|
|
|
8
|
+
const client_root = async app => {
|
|
9
|
+
const root = create_root();
|
|
10
|
+
const code = `export { default as root_${name} } from "root:${name}";`;
|
|
11
|
+
app.build.save(`root:${name}`, root);
|
|
12
|
+
app.build.export(code);
|
|
13
|
+
};
|
|
14
|
+
|
|
3
15
|
export default extension => async (app, next) => {
|
|
4
16
|
const extensions = {
|
|
5
17
|
from: extension,
|
|
@@ -8,8 +20,12 @@ export default extension => async (app, next) => {
|
|
|
8
20
|
|
|
9
21
|
app.register(extension, {
|
|
10
22
|
server: component => server(app, component, extensions),
|
|
11
|
-
client:
|
|
23
|
+
client: component => client(app, component, extensions),
|
|
12
24
|
});
|
|
13
25
|
|
|
26
|
+
await client_root(app);
|
|
27
|
+
app.build.plugin(publish(app, extension));
|
|
28
|
+
app.build.export(expose);
|
|
29
|
+
|
|
14
30
|
return next(app);
|
|
15
31
|
};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import file from "@rcompat/fs/file";
|
|
2
|
+
import compile from "./compile.js";
|
|
3
|
+
import name from "#name";
|
|
4
|
+
|
|
5
|
+
const root_filter = /^root:angular/u;
|
|
6
|
+
|
|
7
|
+
export default (app, extension) => ({
|
|
8
|
+
name,
|
|
9
|
+
setup(build) {
|
|
10
|
+
const resolveDir = app.path.build.path;
|
|
11
|
+
|
|
12
|
+
build.onResolve({ filter: root_filter }, ({ path }) => {
|
|
13
|
+
return { path, namespace: `${name}-root` };
|
|
14
|
+
});
|
|
15
|
+
build.onLoad({ filter: root_filter }, ({ path }) => {
|
|
16
|
+
const contents = app.build.load(path);
|
|
17
|
+
return contents ? { contents, loader: "js", resolveDir } : null;
|
|
18
|
+
});
|
|
19
|
+
build.onLoad({ filter: new RegExp(`${extension}$`, "u") }, async args => {
|
|
20
|
+
// Load the file from the file system
|
|
21
|
+
const source = await file(args.path).text();
|
|
22
|
+
|
|
23
|
+
// Compile component.ts file to JavaScript
|
|
24
|
+
return { contents: await compile(source) };
|
|
25
|
+
});
|
|
26
|
+
},
|
|
27
|
+
});
|
|
@@ -1,18 +1,9 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
const options = {
|
|
4
|
-
loader: "ts",
|
|
5
|
-
tsconfig: {
|
|
6
|
-
compilerOptions: {
|
|
7
|
-
experimentalDecorators: true,
|
|
8
|
-
},
|
|
9
|
-
},
|
|
10
|
-
};
|
|
1
|
+
import compile from "./compile.js";
|
|
11
2
|
|
|
12
3
|
export default async (app, component, extensions) => {
|
|
13
4
|
const location = app.get("location");
|
|
14
5
|
const source = app.runpath(location.components);
|
|
15
|
-
const
|
|
6
|
+
const code = await compile(await component.text());
|
|
16
7
|
const target_base = app.runpath(location.server, location.components);
|
|
17
8
|
const path = target_base.join(`${component.path}.js`.replace(source, ""));
|
|
18
9
|
await path.directory.create();
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
|
|
2
|
+
export default () => `
|
|
3
|
+
import { Component, reflectComponentType } from "@angular/core";
|
|
4
|
+
import stringify from "@rcompat/object/stringify";
|
|
5
|
+
|
|
6
|
+
const root_component = ({ template, imports }) => Component({
|
|
7
|
+
selector: "app-root",
|
|
8
|
+
imports,
|
|
9
|
+
template,
|
|
10
|
+
standalone: true,
|
|
11
|
+
})(class {});
|
|
12
|
+
const double_to_single = string => string.replaceAll('"', "'");
|
|
13
|
+
|
|
14
|
+
export default (component, props) => {
|
|
15
|
+
const { selector } = reflectComponentType(component);
|
|
16
|
+
const attributes = Object.entries(props)
|
|
17
|
+
.map(([key, value]) => \`[\${key}]="\${double_to_single(stringify(value))}"\`)
|
|
18
|
+
.join(" ");
|
|
19
|
+
|
|
20
|
+
return root_component({
|
|
21
|
+
imports: [component],
|
|
22
|
+
template: \`<\${selector} \${attributes}></\${selector}>\`,
|
|
23
|
+
});
|
|
24
|
+
};`;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import root_selector from "#client/root-selector";
|
|
2
|
+
import { Component, reflectComponentType } from "@angular/core";
|
|
3
|
+
import stringify from "@rcompat/object/stringify";
|
|
4
|
+
|
|
5
|
+
const root_component = ({ template, imports }) => Component({
|
|
6
|
+
selector: root_selector,
|
|
7
|
+
imports,
|
|
8
|
+
template,
|
|
9
|
+
standalone: true,
|
|
10
|
+
})(class {});
|
|
11
|
+
|
|
12
|
+
const double_to_single = string => string.replaceAll("\"", "'");
|
|
13
|
+
|
|
14
|
+
export default (component, props) => {
|
|
15
|
+
const { selector } = reflectComponentType(component);
|
|
16
|
+
const attributes = Object.entries(props)
|
|
17
|
+
.map(([key, value]) => `[${key}]="${double_to_single(stringify(value))}"`)
|
|
18
|
+
.join(" ");
|
|
19
|
+
|
|
20
|
+
return root_component({
|
|
21
|
+
imports: [component],
|
|
22
|
+
template: `<${selector} ${attributes}></${selector}>`,
|
|
23
|
+
});
|
|
24
|
+
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export default ({ component, props }) => `
|
|
2
|
+
import { bootstrapApplication, provideClientHydration } from "app";
|
|
3
|
+
import * as components from "app";
|
|
4
|
+
|
|
5
|
+
const config = { providers: [provideClientHydration()] };
|
|
6
|
+
|
|
7
|
+
const rendered = components.root_angular(components.${component},
|
|
8
|
+
${JSON.stringify(props)});
|
|
9
|
+
|
|
10
|
+
bootstrapApplication(rendered, config)
|
|
11
|
+
.catch(error => console.error(error));`;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export default "angular";
|
|
@@ -1,10 +1,29 @@
|
|
|
1
|
-
import serve from "@primate/frontend/core/serve";
|
|
2
1
|
import render from "./render.js";
|
|
3
2
|
import set_mode from "./set-mode.js";
|
|
3
|
+
import client from "#client";
|
|
4
|
+
import normalize from "#normalize";
|
|
4
5
|
|
|
5
|
-
|
|
6
|
+
const serve = (name, props = {}, options = {}) => async app => {
|
|
7
|
+
const component = await app.get_component(name);
|
|
8
|
+
|
|
9
|
+
const normalized = await normalize(name);
|
|
10
|
+
const code = client({ component: normalized, props });
|
|
11
|
+
const inlined = await app.inline(code, "module");
|
|
12
|
+
const script_src = [inlined.integrity];
|
|
13
|
+
|
|
14
|
+
return app.view({
|
|
15
|
+
body: await render(component, props),
|
|
16
|
+
head: inlined.head,
|
|
17
|
+
headers: app.headers({ "script-src": script_src }),
|
|
18
|
+
...options,
|
|
19
|
+
});
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
export default extension => (app, next) => {
|
|
6
23
|
// todo: base on app mode
|
|
7
24
|
set_mode("production");
|
|
8
25
|
|
|
9
|
-
|
|
26
|
+
app.register(extension, serve);
|
|
27
|
+
|
|
28
|
+
return next(app);
|
|
10
29
|
};
|
|
@@ -5,18 +5,18 @@ import {
|
|
|
5
5
|
} from "@angular/platform-browser";
|
|
6
6
|
import {
|
|
7
7
|
provideServerRendering,
|
|
8
|
-
renderApplication,
|
|
9
8
|
ɵSERVER_CONTEXT,
|
|
10
9
|
} from "@angular/platform-server";
|
|
10
|
+
import { CommonEngine } from "@angular/ssr";
|
|
11
11
|
import "zone.js";
|
|
12
|
-
import
|
|
13
|
-
import
|
|
12
|
+
import create_root from "#client/create-root";
|
|
13
|
+
import root_selector from "#client/root-selector";
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
const common_engine = new CommonEngine();
|
|
16
16
|
|
|
17
17
|
export default async (given_component, props) => {
|
|
18
|
-
const component =
|
|
19
|
-
const document = `<${
|
|
18
|
+
const component = create_root(given_component, props);
|
|
19
|
+
const document = `<${root_selector}></${root_selector}>`;
|
|
20
20
|
const bootstrap = () => bootstrapApplication(component, {
|
|
21
21
|
providers: [
|
|
22
22
|
provideServerRendering(),
|
|
@@ -25,9 +25,9 @@ export default async (given_component, props) => {
|
|
|
25
25
|
provideClientHydration(),
|
|
26
26
|
],
|
|
27
27
|
});
|
|
28
|
-
const html = await renderApplication(bootstrap, { document });
|
|
29
28
|
const b_s = "<body>";
|
|
30
29
|
const b_e = "</body>";
|
|
31
|
-
|
|
30
|
+
const html = await common_engine.render({ bootstrap, document });
|
|
31
|
+
|
|
32
32
|
return html.slice(html.indexOf(b_s) + b_s.length, html.indexOf(b_e));
|
|
33
33
|
};
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import { reflectComponentType } from "@angular/core";
|
|
2
|
-
import stringify from "@rcompat/object/stringify";
|
|
3
|
-
import root_component from "./root-component.js";
|
|
4
|
-
|
|
5
|
-
const double_to_single = string => string.replaceAll("\"", "'");
|
|
6
|
-
|
|
7
|
-
export default (real_root, props) => {
|
|
8
|
-
const { selector } = reflectComponentType(real_root);
|
|
9
|
-
const attributes = Object.entries(props)
|
|
10
|
-
.map(([key, value]) => `[${key}]="${double_to_single(stringify(value))}"`)
|
|
11
|
-
.join(" ");
|
|
12
|
-
|
|
13
|
-
return root_component({
|
|
14
|
-
imports: [real_root],
|
|
15
|
-
template: `<${selector} ${attributes}></${selector}>`,
|
|
16
|
-
});
|
|
17
|
-
};
|
|
File without changes
|