elegance-js 2.1.23 → 2.1.26

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 (103) hide show
  1. package/dist/client/effect.d.ts +27 -0
  2. package/dist/client/effect.js +37 -0
  3. package/dist/client/eventListener.d.ts +39 -0
  4. package/dist/client/eventListener.js +52 -0
  5. package/dist/client/loadHook.d.ts +34 -0
  6. package/dist/client/loadHook.js +52 -0
  7. package/dist/client/observer.d.ts +36 -0
  8. package/dist/client/observer.js +66 -0
  9. package/dist/client/runtime.d.ts +105 -0
  10. package/dist/client/runtime.js +620 -0
  11. package/dist/client/state.d.ts +40 -0
  12. package/dist/client/state.js +110 -0
  13. package/dist/compilation/compiler.d.ts +155 -0
  14. package/dist/compilation/compiler.js +1153 -0
  15. package/dist/components/ClientComponent.d.ts +22 -0
  16. package/dist/components/ClientComponent.js +55 -0
  17. package/dist/components/Link.d.ts +16 -1
  18. package/dist/components/Link.js +22 -0
  19. package/dist/components/Portal.d.ts +2 -0
  20. package/dist/components/Portal.js +2 -0
  21. package/dist/elements/element.d.ts +87 -0
  22. package/dist/elements/element.js +33 -0
  23. package/dist/elements/element_list.d.ts +7 -0
  24. package/dist/elements/element_list.js +65 -0
  25. package/dist/elements/raw.d.ts +14 -0
  26. package/dist/elements/raw.js +78 -0
  27. package/dist/elements/specific_props.d.ts +750 -0
  28. package/dist/global.d.ts +221 -327
  29. package/dist/index.d.ts +15 -3
  30. package/dist/index.js +11 -0
  31. package/dist/server/layout.d.ts +34 -3
  32. package/dist/server/layout.js +6 -0
  33. package/dist/server/log.d.ts +12 -0
  34. package/dist/server/log.js +64 -0
  35. package/dist/server/page.d.ts +32 -0
  36. package/dist/server/page.js +6 -0
  37. package/dist/server/runtime.d.ts +6 -0
  38. package/dist/server/runtime.js +72 -0
  39. package/dist/server/server.d.ts +103 -11
  40. package/dist/server/server.js +709 -0
  41. package/package.json +13 -13
  42. package/scripts/bootstrap.js +37 -273
  43. package/scripts/bootstrap_files/elegance.txt +40 -0
  44. package/scripts/bootstrap_files/index.txt +3 -0
  45. package/scripts/bootstrap_files/layout.txt +46 -0
  46. package/scripts/bootstrap_files/middleware.txt +18 -0
  47. package/scripts/bootstrap_files/page.txt +123 -0
  48. package/scripts/bootstrap_files/route.txt +6 -0
  49. package/scripts/elegance_dev.ts +40 -0
  50. package/scripts/elegance_prod.ts +40 -0
  51. package/scripts/elegance_static.ts +24 -0
  52. package/scripts/prod.js +9 -26
  53. package/scripts/run.js +13 -0
  54. package/scripts/static.js +13 -0
  55. package/dist/build.d.ts +0 -2
  56. package/dist/build.mjs +0 -202
  57. package/dist/client/client.d.ts +0 -1
  58. package/dist/client/client.mjs +0 -574
  59. package/dist/client/processPageElements.d.ts +0 -1
  60. package/dist/client/processPageElements.mjs +0 -117
  61. package/dist/client/render.d.ts +0 -1
  62. package/dist/client/render.mjs +0 -40
  63. package/dist/client/watcher.d.ts +0 -1
  64. package/dist/client/watcher.mjs +0 -26
  65. package/dist/compilation/compilation.d.ts +0 -139
  66. package/dist/compilation/compilation.mjs +0 -751
  67. package/dist/compilation/compiler_process.d.ts +0 -3
  68. package/dist/compilation/compiler_process.mjs +0 -102
  69. package/dist/compilation/dynamic_compiler.d.ts +0 -10
  70. package/dist/compilation/dynamic_compiler.mjs +0 -93
  71. package/dist/compile_docs.mjs +0 -34
  72. package/dist/components/Link.mjs +0 -65
  73. package/dist/global.mjs +0 -0
  74. package/dist/helpers/ObjectAttributeType.d.ts +0 -7
  75. package/dist/helpers/ObjectAttributeType.mjs +0 -11
  76. package/dist/helpers/camelToKebab.d.ts +0 -1
  77. package/dist/helpers/camelToKebab.mjs +0 -6
  78. package/dist/index.mjs +0 -3
  79. package/dist/internal/deprecate.d.ts +0 -1
  80. package/dist/internal/deprecate.mjs +0 -7
  81. package/dist/log.d.ts +0 -10
  82. package/dist/log.mjs +0 -38
  83. package/dist/server/generateHTMLTemplate.d.ts +0 -12
  84. package/dist/server/generateHTMLTemplate.mjs +0 -41
  85. package/dist/server/layout.mjs +0 -19
  86. package/dist/server/loadHook.d.ts +0 -30
  87. package/dist/server/loadHook.mjs +0 -50
  88. package/dist/server/observe.d.ts +0 -19
  89. package/dist/server/observe.mjs +0 -16
  90. package/dist/server/render.d.ts +0 -5
  91. package/dist/server/render.mjs +0 -61
  92. package/dist/server/server.mjs +0 -429
  93. package/dist/server/state.d.ts +0 -61
  94. package/dist/server/state.mjs +0 -146
  95. package/dist/shared/bindServerElements.mjs +0 -3
  96. package/dist/shared/serverElements.d.ts +0 -11
  97. package/dist/shared/serverElements.mjs +0 -164
  98. package/scripts/dev.js +0 -33
  99. package/scripts/export.js +0 -20
  100. package/scripts/ts-arc-dev.js +0 -9
  101. package/scripts/ts-arc-prod.js +0 -9
  102. /package/dist/{compile_docs.d.ts → elements/specific_props.js} +0 -0
  103. /package/dist/{shared/bindServerElements.d.ts → global.js} +0 -0
@@ -0,0 +1,110 @@
1
+ import { compilerStore } from "../compilation/compiler.js";
2
+ import { raw } from "../elements/raw.js";
3
+ import { loadHook } from "./loadHook.js";
4
+ class ServerSubject {
5
+ constructor(id, value) {
6
+ this.id = id;
7
+ this.value = value;
8
+ }
9
+ /**
10
+ * Create a client-side reactiveMap, that dynamically updates itself whenever the subject changes.
11
+ *
12
+ * **IMPORTANT** `callback` is sent literally to the browser, and thus doesn't have access to server-side variables, and is untrusted.
13
+ * @param callback Client side templating function that gets each entry of T, and returns an EleganceElement.
14
+ * @returns An HTML represent used to track the position of the reactive map.
15
+ */
16
+ reactiveMap(callback) {
17
+ if (!callback) {
18
+ throw new Error("No template provided for reactiveMap.");
19
+ }
20
+ if (Array.isArray(this.value) === false) {
21
+ throw new Error("Reactive maps can only be used on arrays.");
22
+ }
23
+ const store = compilerStore.getStore();
24
+ if (!store) {
25
+ throw new Error("reactiveMap() can only be invoked during the build process of a page or layout.");
26
+ }
27
+ const mapId = state(store.generateId());
28
+ const templateState = state(callback);
29
+ loadHook((templateState, thisState, mapId) => {
30
+ let trackedElements = [];
31
+ function updateCallback() {
32
+ const mapTemplateElement = document.querySelector(`template[map-id="${mapId.value}"]`);
33
+ if (!mapTemplateElement) {
34
+ DEV_BUILD: throw new Error("The DOM has been mutated and no longer contains the required template element to create an track the reactiveMap of subject with id: " + thisState.id);
35
+ return;
36
+ }
37
+ for (const elem of trackedElements) {
38
+ elem.parentElement?.removeChild(elem);
39
+ }
40
+ trackedElements = [];
41
+ for (const value of thisState.value) {
42
+ const result = templateState.value(value);
43
+ const instanceHTML = eleganceClient.createHTMLElementFromElement(result);
44
+ mapTemplateElement.parentElement?.insertBefore(instanceHTML.root, mapTemplateElement);
45
+ trackedElements.push(instanceHTML.root);
46
+ }
47
+ }
48
+ const callbackId = Date.now().toString();
49
+ thisState.observe(callbackId, updateCallback);
50
+ updateCallback();
51
+ return () => {
52
+ thisState.unobserve(callbackId);
53
+ };
54
+ }, [templateState, this, mapId]);
55
+ return template({ "map-id": mapId.value, });
56
+ }
57
+ /**
58
+ * Allows the use of a ServerSubject as the child of an EleganceElement.
59
+ *
60
+ * Returns an HTML string that will be removed on page-load in the client and replaced with the appropriate value.
61
+ * @returns HTML string
62
+ */
63
+ generateObserverNode() {
64
+ return raw(`<template o="${this.id}"></template>`);
65
+ }
66
+ toString() {
67
+ return this.generateObserverNode();
68
+ }
69
+ serialize() {
70
+ let result = `{id:"${this.id}",value:`;
71
+ switch (typeof this.value) {
72
+ case "string":
73
+ result += `"${this.value}"`;
74
+ break;
75
+ case "function":
76
+ result += `${this.value.toString()}`;
77
+ break;
78
+ case "object":
79
+ if (Array.isArray(this.value)) {
80
+ result += `${JSON.stringify(this.value)}`;
81
+ break;
82
+ }
83
+ default:
84
+ result += JSON.stringify(this.value);
85
+ break;
86
+ }
87
+ result += "}";
88
+ return result;
89
+ }
90
+ }
91
+ /**
92
+ * Create a reactive ServerSubject which will be serialized and sent to the browser.
93
+ *
94
+ * Once in the callback of a loadHook, eventListener, etc. it will become a *ClientSubject*.
95
+ * @param value Any value you want to be accessible in the browser. Value is sent literally as-is. Functions are supported.
96
+ * @param options Set options for the state (usually unused)
97
+ * @returns An instance of ServerSubject you can use as a reference to this state in functions like `loadHook()`
98
+ */
99
+ function state(value, options) {
100
+ const store = compilerStore.getStore();
101
+ if (!store) {
102
+ const message = "Illegal invocation of state(). Ensure that the state() function is only called inside components, and never at the top-level of a page or layout.";
103
+ throw new Error(message);
104
+ }
105
+ const subjectId = options?.explicitId ?? store.generateId();
106
+ const serverSubject = new ServerSubject(subjectId, value);
107
+ store.addClientToken(serverSubject);
108
+ return serverSubject;
109
+ }
110
+ export { state, ServerSubject, };
@@ -0,0 +1,155 @@
1
+ /**
2
+ * This file contains the functions used by compiler_process to compile pages.
3
+ */
4
+ import { AnyElement, SpecialElementOption } from "../elements/element";
5
+ import { PageInformation } from "../server/page";
6
+ import { LayoutInformation, LayoutProps } from "../server/layout";
7
+ import { AsyncLocalStorage } from "async_hooks";
8
+ import { IncomingMessage, ServerResponse } from "http";
9
+ /** Context of a page that is currently being compiled. */
10
+ type PageCompilationContext = {
11
+ /** The slash starting relative pathname (relative to pagesDirectory) of this page. */
12
+ pathname: string;
13
+ /**
14
+ * An id counter starting from 0, that is incremented once per generateID() call,
15
+ * and is used in conjunction with the pathname to generate unique static IDs (order-dependent)
16
+ */
17
+ idCounter: number;
18
+ usedHashes: string[];
19
+ /**
20
+ * Used by some tools to determine whether or not the current context is a page or a layout,
21
+ * useful for stuff like loadHooks, which behave differently in layouts and pages.
22
+ */
23
+ kind: "page" | "layout";
24
+ };
25
+ /** Context of a layout that is currently being compiled. */
26
+ type LayoutCompilationContext = {
27
+ /** The slash starting relative pathname (relative to pagesDirectory) of this layout. */
28
+ pathname: string;
29
+ /**
30
+ * An id counter starting from 0, that is incremented once per generateID() call,
31
+ * and is used in conjunction with the pathname to generate unique static IDs (order-dependent)
32
+ */
33
+ idCounter: number;
34
+ usedHashes: string[];
35
+ /**
36
+ * Used by some tools to determine whether or not the current context is a page or a layout,
37
+ * useful for stuff like loadHooks, which behave differently in layouts and pages.
38
+ */
39
+ kind: "layout" | "page";
40
+ };
41
+ type CompilerOptions = {
42
+ pagesDirectory: string;
43
+ environment: "production" | "development";
44
+ publicDirectory: string;
45
+ outputDirectory: string;
46
+ doHotReload: boolean;
47
+ };
48
+ type CompiledLayout = {
49
+ /** Compiled result of the layoutConstructor */
50
+ layoutHTMLStart: string;
51
+ layoutHTMLEnd: string;
52
+ /** Client data tokens generated by the layoutConstructor & layoutMetadataConstructor during it's compilation. */
53
+ specialElementOptions: {
54
+ elementKey: string;
55
+ optionName: string;
56
+ optionValue: SpecialElementOption;
57
+ }[];
58
+ clientTokens: unknown[];
59
+ /** Compiled result of the layoutMetadataConstructor */
60
+ layoutMetadataHTML: string;
61
+ layoutProps: LayoutProps;
62
+ };
63
+ type CompiledPage = {
64
+ pageHTML: string;
65
+ };
66
+ /** The result of turning an element into a string and extracting any special options from it. */
67
+ type SerializationResult = {
68
+ serializedElement: string;
69
+ specialElementOptions: {
70
+ elementKey: string;
71
+ optionName: string;
72
+ optionValue: SpecialElementOption;
73
+ }[];
74
+ };
75
+ declare let compilerOptions: CompilerOptions;
76
+ /**
77
+ * We use asynclocalstorage instead of globals to get rid of race conditions.
78
+ * We run the code inside asynclocalstorage, and then all of the values get dumped into here instead of globalThis.
79
+ * A much cleaner approach than previous.
80
+ */
81
+ type CompilerStore = {
82
+ generateId: () => string;
83
+ addClientToken: (value: unknown) => void;
84
+ compilationContext: PageCompilationContext | LayoutCompilationContext;
85
+ req?: IncomingMessage;
86
+ res?: ServerResponse;
87
+ };
88
+ declare const compilerStore: AsyncLocalStorage<CompilerStore>;
89
+ declare function setCompilerOptions(newOptions: CompilerOptions): void;
90
+ declare function generatePageCompilationContext(pathname: string): PageCompilationContext;
91
+ declare function generateLayoutCompilationContext(pathname: string): LayoutCompilationContext;
92
+ /**
93
+ * Ship any `node_modules` package to the browser.
94
+ * @param packages The packages to register for shipping to the browser.
95
+ */
96
+ declare function clientPackages(packages: {
97
+ [globalName: string]: string;
98
+ }): void;
99
+ /**
100
+ * Take any element, and turn it into a valid HTML string.
101
+ * Throw an error whenever an element is considered invalid.
102
+ * @param compilationContext The context of the page or layout that we're compiling
103
+ * @param element The element to serialize.
104
+ * @returns The serialized element, and any special options that were encountered.
105
+ */
106
+ declare function serializeElement(compilationContext: PageCompilationContext, element: AnyElement, path?: string[]): SerializationResult;
107
+ /**
108
+ * This function uses string interpolation to transform client tokens and special element options into a script tag that is then sent to the client.
109
+ * The client tokens are not *fully* serialized, but the necessary components to re-create them as client versions of the corresponding thing *are* serialized.
110
+ * For example, the serialize() method of EventListener is not sent, but it's callback, id, and dependencies (as ids) are.
111
+ * String interpolation is dangerous and error-prone, so if you're going to add something to this function, ensure you know what you're doing,
112
+ * and make sure to also edit runtime.ts to handle the clientTokens that you send to the browser. I did not create separate datatypes in the runtime for the intermediary forms of things like EventListeners,
113
+ * LoadHooks, etc, for I did not feel it necessary, but do note that these types do not exactly line up 100%.
114
+ * @param compilationContext The current context of what we're compiling, can be either layout or page compilation context.
115
+ * @param specialElementOptions An array of special element options that were found during serialization of the elements of whatever we're currently compiling
116
+ * @param clientTokens An array of tokens that will be serialized and shipped within the pageDataScript.
117
+ * @returns A string containing the page data <script> tag.
118
+ */
119
+ declare function generatePageDataScript(compilationContext: PageCompilationContext, specialElementOptions: {
120
+ elementKey: string;
121
+ optionName: string;
122
+ optionValue: SpecialElementOption;
123
+ }[], clientTokens: unknown[]): Promise<string>;
124
+ declare function compilePageToDisk(allLayouts: Map<string, LayoutInformation>, pageInformation: PageInformation): Promise<CompiledPage>;
125
+ declare function compilePage(allLayouts: Map<string, LayoutInformation>, pageInformation: PageInformation, reqRes?: {
126
+ req?: IncomingMessage | undefined;
127
+ res?: ServerResponse | undefined;
128
+ }, extraParams?: Record<string, unknown>): Promise<CompiledPage>;
129
+ declare function compileLayoutToDisk(layoutInformation: LayoutInformation, allLayouts: Map<string, LayoutInformation>): Promise<void>;
130
+ declare function compileLayout(layoutInformation: LayoutInformation, allLayouts: Map<string, LayoutInformation>, reqRes?: {
131
+ req?: IncomingMessage;
132
+ res?: ServerResponse;
133
+ }): Promise<CompiledLayout>;
134
+ /**
135
+ * Run the general compilation process for the project.
136
+ * This compiles all static-pages & static-layouts, as well as gathers a list of every page (dynamic and static) & layout (dynamic and static).
137
+ * It also recursively copies your public directory into the distribution directory.
138
+ * If doHotReload is true, it will also enable hot-reloading.
139
+ */
140
+ declare function compileEntireProject(): Promise<{
141
+ allPages: Map<string, PageInformation>;
142
+ allLayouts: Map<string, LayoutInformation>;
143
+ allStatusCodePages: Map<string, PageInformation>;
144
+ compiledStaticPages: Map<string, CompiledPage>;
145
+ compiledStaticLayouts: Map<string, CompiledLayout>;
146
+ }>;
147
+ /**
148
+ * Run the general compilation process for the project.
149
+ * This compiles all static-pages & static-layouts, as well as gathers a list of every page (dynamic and static) & layout (dynamic and static).
150
+ * It then writes those values to compilerOptions -> outputDirectory/DIST
151
+ * It also recursively copies your public directory into the distribution directory.
152
+ */
153
+ declare function compileEntireProjectToDisk(): Promise<void>;
154
+ export type { CompilerOptions, CompiledLayout, CompiledPage, };
155
+ export { setCompilerOptions, generatePageCompilationContext, generateLayoutCompilationContext, serializeElement, generatePageDataScript, compileEntireProject, compileEntireProjectToDisk, compilePageToDisk, compileLayoutToDisk, compilerStore, compilerOptions, compilePage, compileLayout, clientPackages, };