elegance-js 1.17.4 → 2.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.
@@ -438,7 +438,36 @@ var navigateLocally = async (target, pushState = true) => {
438
438
  }
439
439
  }
440
440
  oldPageLatest.replaceWith(newPageLatest);
441
- doc.head.replaceWith(newPage.head);
441
+ {
442
+ doc.head.querySelector("title")?.replaceWith(
443
+ newPage.head.querySelector("title") ?? ""
444
+ );
445
+ const update = (targetList, matchAgainst, action) => {
446
+ for (const target2 of targetList) {
447
+ const matching = matchAgainst.find((n) => n.isEqualNode(target2));
448
+ if (matching) {
449
+ continue;
450
+ }
451
+ action(target2);
452
+ }
453
+ };
454
+ const oldTags = Array.from([
455
+ ...Array.from(document.head.querySelectorAll("link")),
456
+ ...Array.from(document.head.querySelectorAll("meta")),
457
+ ...Array.from(document.head.querySelectorAll("script")),
458
+ ...Array.from(document.head.querySelectorAll("base")),
459
+ ...Array.from(document.head.querySelectorAll("style"))
460
+ ]);
461
+ const newTags = Array.from([
462
+ ...Array.from(newPage.head.querySelectorAll("link")),
463
+ ...Array.from(newPage.head.querySelectorAll("meta")),
464
+ ...Array.from(newPage.head.querySelectorAll("script")),
465
+ ...Array.from(newPage.head.querySelectorAll("base")),
466
+ ...Array.from(newPage.head.querySelectorAll("style"))
467
+ ]);
468
+ update(newTags, oldTags, (node) => document.head.appendChild(node));
469
+ update(oldTags, newTags, (node) => node.remove());
470
+ }
442
471
  if (pushState) history.pushState(null, "", targetURL.href);
443
472
  loadPage(currentPage);
444
473
  currentPage = pathname;
package/dist/global.d.ts CHANGED
@@ -40,7 +40,11 @@ declare global {
40
40
  type Layout = ((child: Child) => (AnyBuiltElement | Promise<AnyBuiltElement>));
41
41
  /** The type for const metadata in layout.ts files. */
42
42
  type LayoutMetadata = ((child: Child) => (AnyBuiltElement | Promise<AnyBuiltElement>));
43
- type Page = (AnyBuiltElement) | (() => AnyBuiltElement) | (() => Promise<AnyBuiltElement>);
43
+ /** Parameters that get passed into Page */
44
+ type PageProps = {
45
+ pageName: string;
46
+ };
47
+ type Page = (AnyBuiltElement) | ((props: PageProps) => AnyBuiltElement | Promise<AnyBuiltElement>);
44
48
  type Metadata = (() => (AnyBuiltElement)) | (() => Promise<AnyBuiltElement>);
45
49
  type ObjectAttribute<T> = T extends ObjectAttributeType.STATE ? {
46
50
  type: ObjectAttributeType;
@@ -629,8 +629,7 @@ var generateClientPageData = async (pageLocation, state, objectAttributes, pageL
629
629
  fs.writeFileSync(pageDataPath, transformedResult.code, "utf-8");
630
630
  return { sendHardReloadInstruction };
631
631
  };
632
- var generateLayout = async (DIST_DIR2, filePath, childIndicator) => {
633
- const directory = path.dirname(filePath);
632
+ var generateLayout = async (DIST_DIR2, filePath, directory, childIndicator) => {
634
633
  initializeState();
635
634
  initializeObjectAttributes();
636
635
  resetLoadHooks();
@@ -651,27 +650,8 @@ var generateLayout = async (DIST_DIR2, filePath, childIndicator) => {
651
650
  layoutElements = layout;
652
651
  metadataElements = metadata;
653
652
  if (isDynamic === true) {
654
- const result = await esbuild.build({
655
- entryPoints: [filePath],
656
- bundle: false,
657
- format: "iife",
658
- globalName: "__exports",
659
- write: false,
660
- platform: "node",
661
- plugins: [externalPackagesPlugin]
662
- });
663
- let iifeCode = result.outputFiles[0].text;
664
- iifeCode = iifeCode.replace(/^var __exports = /, "");
665
- const wrappedCode = `import { createRequire } from 'module'; const require = createRequire(import.meta.url);
666
-
667
- export function construct() {
668
- ${iifeCode}
669
- return __exports
670
- }`;
671
- fs.writeFileSync(filePath, wrappedCode);
672
- return { pageContentHTML: "", metadataHTML: "" };
653
+ throw new Error("ts-arc in Elegance does not support dynamic pages yet.");
673
654
  }
674
- fs.rmSync(filePath, { force: true });
675
655
  } catch (e) {
676
656
  throw new Error(`Error in Page: ${directory === "" ? "/" : directory}layout.mjs - ${e}`);
677
657
  }
@@ -709,12 +689,11 @@ return __exports
709
689
  const stack = [];
710
690
  const processedPageElements = processPageElements(layoutElements, foundObjectAttributes, 0, stack);
711
691
  const renderedPage = await serverSideRenderPage(
712
- processedPageElements,
713
- path.dirname(filePath)
692
+ processedPageElements
714
693
  );
715
694
  const metadataHTML = metadataElements ? renderRecursively(metadataElements) : "";
716
695
  await generateClientPageData(
717
- path.dirname(filePath),
696
+ path.dirname(path.join(DIST_DIR2, "dist", directory)),
718
697
  state || {},
719
698
  [...objectAttributes, ...foundObjectAttributes],
720
699
  pageLoadHooks || [],
@@ -725,7 +704,7 @@ return __exports
725
704
  return { pageContentHTML: renderedPage.bodyHTML, metadataHTML };
726
705
  };
727
706
  var builtLayouts = /* @__PURE__ */ new Map();
728
- var buildLayout = async (filePath) => {
707
+ var buildLayout = async (filePath, directory) => {
729
708
  const storedState = globalThis.__SERVER_CURRENT_STATE__;
730
709
  const storedObjectAttributes = globalThis.__SERVER_CURRENT_OBJECT_ATTRIBUTES__;
731
710
  const storedLoadHooks = globalThis.__SERVER_CURRENT_LOADHOOKS__;
@@ -735,6 +714,7 @@ var buildLayout = async (filePath) => {
735
714
  const { pageContentHTML, metadataHTML } = await generateLayout(
736
715
  DIST_DIR,
737
716
  filePath,
717
+ directory,
738
718
  childIndicator
739
719
  );
740
720
  const splitAround = (str, sub) => {
@@ -753,7 +733,7 @@ var buildLayout = async (filePath) => {
753
733
  endHTML: str.substring(i)
754
734
  };
755
735
  };
756
- const pageURL = path.relative(DIST_DIR, path.dirname(filePath));
736
+ const pageURL = directory;
757
737
  globalThis.__SERVER_CURRENT_STATE__ = storedState;
758
738
  globalThis.__SERVER_CURRENT_OBJECT_ATTRIBUTES__ = storedObjectAttributes;
759
739
  globalThis.__SERVER_CURRENT_LOADHOOKS__ = storedLoadHooks;
@@ -761,21 +741,21 @@ var buildLayout = async (filePath) => {
761
741
  return {
762
742
  pageContent: splitAt(pageContentHTML, childIndicator),
763
743
  metadata: splitAround(metadataHTML, childIndicator),
764
- scriptTag: `<script data-layout="true" type="module" src="${pageURL === "" ? "" : "/"}${pageURL}/layout_data.js" defer="true"></script>`
744
+ scriptTag: `<script data-layout="true" type="module" src="${pageURL}${pageURL === "/" ? "" : "/"}layout_data.js" defer="true"></script>`
765
745
  };
766
746
  };
767
747
  var fetchPageLayoutHTML = async (dirname) => {
768
- const relative = path.relative(DIST_DIR, dirname);
748
+ const relative = path.relative(options.pagesDirectory, dirname);
769
749
  let split = relative.split(path.sep).filter(Boolean);
770
750
  split.push("/");
771
751
  split.reverse();
772
752
  let layouts = [];
773
753
  for (const dir of split) {
774
- const filePath = path.resolve(path.join(DIST_DIR, dir, "layout.mjs"));
754
+ const filePath = path.resolve(path.join(options.pagesDirectory, dir, "layout.ts"));
775
755
  if (builtLayouts.has(filePath)) {
776
756
  layouts.push(builtLayouts.get(filePath));
777
757
  } else if (fs.existsSync(filePath)) {
778
- const built = await buildLayout(filePath);
758
+ const built = await buildLayout(filePath, dir);
779
759
  builtLayouts.set(filePath, built);
780
760
  layouts.push(built);
781
761
  }
@@ -800,14 +780,15 @@ var fetchPageLayoutHTML = async (dirname) => {
800
780
  };
801
781
  var buildPages = async (DIST_DIR2) => {
802
782
  resetLayouts();
803
- const subdirectories = [...getAllSubdirectories(DIST_DIR2), ""];
783
+ const pagesDirectory = path.resolve(options.pagesDirectory);
784
+ const subdirectories = [...getAllSubdirectories(pagesDirectory), ""];
804
785
  let shouldClientHardReload = false;
805
786
  for (const directory of subdirectories) {
806
- const abs = path.resolve(path.join(DIST_DIR2, directory));
807
- const files = fs.readdirSync(abs, { withFileTypes: true }).filter((f) => f.name.endsWith(".mjs"));
787
+ const abs = path.resolve(path.join(pagesDirectory, directory));
788
+ const files = fs.readdirSync(abs, { withFileTypes: true }).filter((f) => f.name.endsWith(".ts"));
808
789
  for (const file of files) {
809
790
  const filePath = path.join(file.parentPath, file.name);
810
- const name = file.name.slice(0, file.name.length - 4);
791
+ const name = file.name.slice(0, file.name.length - 3);
811
792
  const isPage = file.name.includes("page");
812
793
  if (isPage == false) {
813
794
  continue;
@@ -853,29 +834,10 @@ var buildPage = async (DIST_DIR2, directory, filePath, name) => {
853
834
  pageElements = page;
854
835
  metadata = pageMetadata;
855
836
  if (isDynamicPage === true) {
856
- const result = await esbuild.build({
857
- entryPoints: [filePath],
858
- bundle: false,
859
- format: "iife",
860
- globalName: "__exports",
861
- write: false,
862
- platform: "node",
863
- plugins: [externalPackagesPlugin]
864
- });
865
- let iifeCode = result.outputFiles[0].text;
866
- iifeCode = iifeCode.replace(/^var __exports = /, "");
867
- const wrappedCode = `import { createRequire } from 'module'; const require = createRequire(import.meta.url);
868
-
869
- export function construct() {
870
- ${iifeCode}
871
- return __exports
872
- }`;
873
- fs.writeFileSync(filePath, wrappedCode);
874
- return false;
837
+ throw new Error("Dynamic page is not yet supported with ts-arc");
875
838
  }
876
- fs.rmSync(filePath, { force: true });
877
839
  } catch (e) {
878
- throw new Error(`Error in Page: ${directory === "" ? "/" : directory}${name}.mjs - ${e}`);
840
+ throw new Error(`Error in Page: ${directory === "" ? "/" : directory}${name}.ts - ${e}`);
879
841
  }
880
842
  if (!metadata || metadata && typeof metadata !== "function") {
881
843
  console.warn(`WARNING: ${filePath} does not export a metadata function. This is *highly* recommended.`);
@@ -883,11 +845,14 @@ return __exports
883
845
  if (!pageElements) {
884
846
  console.warn(`WARNING: ${filePath} should export a const page, which is of type () => BuiltElement<"body">.`);
885
847
  }
848
+ const pageProps = {
849
+ pageName: directory
850
+ };
886
851
  if (typeof pageElements === "function") {
887
852
  if (pageElements.constructor.name === "AsyncFunction") {
888
- pageElements = await pageElements();
853
+ pageElements = await pageElements(pageProps);
889
854
  } else {
890
- pageElements = pageElements();
855
+ pageElements = pageElements(pageProps);
891
856
  }
892
857
  }
893
858
  const state = getState();
@@ -895,7 +860,7 @@ return __exports
895
860
  const objectAttributes = getObjectAttributes();
896
861
  const layout = await fetchPageLayoutHTML(path.dirname(filePath));
897
862
  const foundObjectAttributes = await pageToHTML(
898
- path.dirname(filePath),
863
+ path.dirname(path.join(DIST_DIR2, "dist", directory)),
899
864
  pageElements || body(),
900
865
  metadata ?? (() => head()),
901
866
  DIST_DIR2,
@@ -907,7 +872,7 @@ return __exports
907
872
  const {
908
873
  sendHardReloadInstruction
909
874
  } = await generateClientPageData(
910
- path.dirname(filePath),
875
+ path.dirname(path.join(DIST_DIR2, "dist", directory)),
911
876
  state || {},
912
877
  [...objectAttributes, ...foundObjectAttributes],
913
878
  pageLoadHooks || [],
@@ -917,91 +882,8 @@ return __exports
917
882
  return sendHardReloadInstruction === true;
918
883
  };
919
884
  var recursionFlag = Symbol("external-node-modules-recursion");
920
- var externalPackagesPlugin = {
921
- name: "external-packages",
922
- setup(build2) {
923
- build2.onResolve({ filter: /^[^./]/ }, async (args) => {
924
- if (args.pluginData?.[recursionFlag]) {
925
- return;
926
- }
927
- const result = await build2.resolve(args.path, {
928
- resolveDir: args.resolveDir,
929
- kind: args.kind,
930
- importer: args.importer,
931
- pluginData: { [recursionFlag]: true }
932
- });
933
- if (result.errors.length > 0 || result.external || !result.path) {
934
- return { path: args.path, external: true };
935
- }
936
- const nodeModulesIndex = result.path.indexOf("node_modules");
937
- if (nodeModulesIndex === -1) {
938
- return result;
939
- }
940
- const isNested = result.path.includes("node_modules", nodeModulesIndex + 14);
941
- if (args.path.startsWith("elegance-js")) {
942
- return result;
943
- }
944
- if (isNested) {
945
- return { path: args.path, external: true };
946
- }
947
- return { path: args.path, external: true };
948
- });
949
- }
950
- };
951
885
  var shippedPlugins = /* @__PURE__ */ new Map();
952
886
  var pluginsToShip = [];
953
- var shipPlugin = {
954
- name: "ship",
955
- setup(build2) {
956
- build2.onLoad({ filter: /\.(js|ts|jsx|tsx)$/ }, async (args) => {
957
- let contents = await fs.promises.readFile(args.path, "utf8");
958
- const lines = contents.split(/\r?\n/);
959
- let prepender = "";
960
- for (let i = 0; i < lines.length - 1; i++) {
961
- if (lines[i].trim() === "//@ship") {
962
- const nextLine = lines[i + 1].trim();
963
- const starRegex = /import\s*\*\s*as\s*(\w+)\s*from\s*["']([^"']+)["']\s*;/;
964
- const defaultRegex = /import\s*(\w+)\s*from\s*["']([^"']+)["']\s*;/;
965
- let match = nextLine.match(starRegex);
966
- let importName;
967
- let pkgPath;
968
- if (match) {
969
- importName = match[1];
970
- pkgPath = match[2];
971
- } else {
972
- match = nextLine.match(defaultRegex);
973
- if (match) {
974
- importName = match[1];
975
- pkgPath = match[2];
976
- } else {
977
- continue;
978
- }
979
- }
980
- if (prepender === "") {
981
- prepender = "export const requiredClientModules = [\n";
982
- }
983
- prepender += `"${importName}",
984
- `;
985
- pluginsToShip.push({
986
- path: pkgPath,
987
- globalName: importName
988
- });
989
- const replacement = `const ${importName} = globalThis.${importName};`;
990
- lines.splice(i, 2, replacement);
991
- i--;
992
- }
993
- }
994
- if (prepender !== "") {
995
- prepender += "];";
996
- }
997
- contents = lines.join("\n");
998
- return {
999
- contents: prepender + contents,
1000
- loader: path.extname(args.path).slice(1)
1001
- };
1002
- });
1003
- }
1004
- };
1005
887
  var build = async () => {
1006
888
  if (options.quiet === true) {
1007
889
  console.log = function() {
@@ -1038,23 +920,6 @@ var build = async () => {
1038
920
  const start = performance.now();
1039
921
  {
1040
922
  pluginsToShip = [];
1041
- await esbuild.build({
1042
- entryPoints: projectFiles.map((f) => path.join(f.parentPath, f.name)),
1043
- bundle: true,
1044
- outdir: DIST_DIR,
1045
- outExtension: { ".js": ".mjs" },
1046
- plugins: [externalPackagesPlugin, shipPlugin],
1047
- loader: {
1048
- ".ts": "ts"
1049
- },
1050
- format: "esm",
1051
- platform: "node",
1052
- keepNames: false,
1053
- define: {
1054
- "DEV": options.environment === "development" ? "true" : "false",
1055
- "PROD": options.environment === "development" ? "false" : "true"
1056
- }
1057
- });
1058
923
  for (const plugin of pluginsToShip) {
1059
924
  {
1060
925
  if (shippedPlugins.has(plugin.globalName)) continue;
@@ -1,5 +1,5 @@
1
1
  import "../shared/bindServerElements";
2
2
  export declare const renderRecursively: (element: Child) => string;
3
- export declare const serverSideRenderPage: (page: Page, pathname: string) => Promise<{
3
+ export declare const serverSideRenderPage: (page: Page, pathname?: string) => Promise<{
4
4
  bodyHTML: string;
5
5
  }>;
package/package.json CHANGED
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "name": "elegance-js",
3
- "version": "1.17.4",
3
+ "version": "2.0.0",
4
4
  "description": "Web-Framework",
5
5
  "type": "module",
6
6
  "bin": {
7
- "dev": "./scripts/dev.js",
8
- "prod": "./scripts/prod.js",
9
- "static": "./scripts/export.js",
10
- "bootstrap": "./scripts/bootstrap.js"
7
+ "dev": "./scripts/ts-arc-dev.js",
8
+ "prod": "./scripts/ts-arc-prod.js",
9
+ "bootstrap": "./scripts/bootstrap.js",
10
+ "native": "./scripts/native-test.js"
11
11
  },
12
12
  "scripts": {
13
13
  "build": "esbuild --format=esm --platform=node --bundle --outdir=./dist --platform=node --external:esbuild --out-extension:.js=.mjs \"./src/**/*.ts\" && tsc",
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env node
2
+ import { spawnSync } from "node:child_process";
3
+ import { fileURLToPath } from "node:url";
4
+ import { dirname, join } from "node:path";
5
+
6
+ const __dirname = dirname(fileURLToPath(import.meta.url));
7
+ const target = join(__dirname, "./dev.js");
8
+
9
+ spawnSync("npx", ["ts-arc", target], { stdio: "inherit" });
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env node
2
+ import { spawnSync } from "node:child_process";
3
+ import { fileURLToPath } from "node:url";
4
+ import { dirname, join } from "node:path";
5
+
6
+ const __dirname = dirname(fileURLToPath(import.meta.url));
7
+ const target = join(__dirname, "./prod.js");
8
+
9
+ spawnSync("npx", ["ts-arc", target], { stdio: "inherit" });
package/scripts/dev.js DELETED
@@ -1,33 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- import { compile } from "elegance-js/build"
4
- import { exec, execSync } from "node:child_process";
5
-
6
- let child = undefined;
7
-
8
- compile({
9
- environment: "development",
10
- outputDirectory: ".elegance",
11
- pagesDirectory: "./pages",
12
- publicDirectory: {
13
- method: "recursive-copy",
14
- path: "./public",
15
- },
16
- hotReload: {
17
- port: 3001,
18
- hostname: "localhost",
19
- },
20
- server: {
21
- runServer: true,
22
- port: 3000,
23
- },
24
- postCompile: () => {
25
- if (child !== undefined) {
26
- child.kill('SIGKILL');
27
- }
28
-
29
- const childProcess = exec("npx @tailwindcss/cli -i \"./index.css\" -o \"../.elegance/dist/index.css\" --cwd \"./pages\" --watch")
30
-
31
- child = childProcess;
32
- },
33
- })
package/scripts/export.js DELETED
@@ -1,20 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- import { compile } from "elegance-js/build"
4
- import { exec, execSync } from "node:child_process";
5
-
6
- compile({
7
- environment: "production",
8
- outputDirectory: ".elegance",
9
- pagesDirectory: "./pages",
10
- publicDirectory: {
11
- method: "recursive-copy",
12
- path: "./public",
13
- },
14
- server: {
15
- runServer: false,
16
- },
17
- postCompile: () => {
18
- exec("npx @tailwindcss/cli -i \"./index.css\" -o \"../.elegance/dist/index.css\" --cwd \"./pages\" --minify=true")
19
- },
20
- })
package/scripts/prod.js DELETED
@@ -1,29 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- import { compile } from "elegance-js/build"
4
- import { exec, execSync } from "node:child_process";
5
-
6
- let child = undefined;
7
-
8
- compile({
9
- environment: "production",
10
- outputDirectory: ".elegance",
11
- pagesDirectory: "./pages",
12
- publicDirectory: {
13
- method: "recursive-copy",
14
- path: "./public",
15
- },
16
- server: {
17
- runServer: true,
18
- port: 3000,
19
- },
20
- postCompile: () => {
21
- if (child !== undefined) {
22
- child.kill('SIGKILL');
23
- }
24
-
25
- const childProcess = execSync("npx @tailwindcss/cli -i \"./index.css\" -o \"../.elegance/dist/index.css\" --cwd \"./pages\" --minify=true")
26
-
27
- child = childProcess;
28
- },
29
- })