@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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@primate/angular",
3
- "version": "0.1.4",
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.1.4",
19
- "@angular/platform-browser": "^18.1.4",
20
- "@angular/platform-server": "^18.1.4",
21
- "@angular/ssr": "^18.1.4",
22
- "@rcompat/build": "^0.4.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.1"
27
+ "@primate/frontend": "^0.16.4"
26
28
  },
27
29
  "peerDependencies": {
28
30
  "@angular/core": "18",
29
- "primate": "^0.32.2"
31
+ "primate": "^0.32.6"
30
32
  },
31
33
  "type": "module",
32
34
  "imports": {
33
35
  "#*": {
34
- "@primate/lt": "./src/private/*.js",
36
+ "livetypes": "./src/private/*.js",
35
37
  "default": "./src/private/*.js"
36
38
  },
37
39
  "#build": {
38
- "@primate/lt": "./src/private/build/index.js",
40
+ "livetypes": "./src/private/build/index.js",
39
41
  "default": "./src/private/build/index.js"
40
42
  },
41
43
  "#serve": {
42
- "@primate/lt": "./src/private/serve/index.js",
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
+ };
@@ -0,0 +1,12 @@
1
+ import transform from "@rcompat/build/transform";
2
+
3
+ const options = {
4
+ loader: "ts",
5
+ tsconfig: {
6
+ compilerOptions: {
7
+ experimentalDecorators: true,
8
+ },
9
+ },
10
+ };
11
+
12
+ export default async text => (await transform(text, options)).code;
@@ -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 transform from "@rcompat/build/transform";
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 { code } = await transform(await component.text(), options);
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,9 @@
1
+ export default `
2
+ // side effects
3
+ import "@angular/compiler";
4
+ import "zone.js";
5
+
6
+ export {
7
+ bootstrapApplication,
8
+ provideClientHydration,
9
+ } from "@angular/platform-browser";`;
@@ -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";
@@ -0,0 +1,4 @@
1
+ import hash from "@rcompat/crypto/hash";
2
+ import name from "#name";
3
+
4
+ export default async path => `${name}_${await hash(path)}`;
@@ -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
- export default extension => {
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
- return serve({ render })(extension);
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 make_root from "./make-root.js";
13
- import selector from "./selector.js";
12
+ import create_root from "#client/create-root";
13
+ import root_selector from "#client/root-selector";
14
14
 
15
- // const common_engine = new CommonEngine();
15
+ const common_engine = new CommonEngine();
16
16
 
17
17
  export default async (given_component, props) => {
18
- const component = make_root(given_component, props);
19
- const document = `<${selector}></${selector}>`;
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
- // await common_engine.render({ bootstrap, document });
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
- };
@@ -1,9 +0,0 @@
1
- import { Component as component } from "@angular/core";
2
- import selector from "./selector.js";
3
-
4
- export default ({ template, imports }) => component({
5
- selector,
6
- imports,
7
- template,
8
- standalone: true,
9
- })(class {});