elegance-js 1.15.2 → 1.17.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/dist/build.mjs +7 -5
- package/dist/client/client.mjs +96 -92
- package/dist/client/watcher.mjs +2 -1
- package/dist/compile_docs.mjs +7 -5
- package/dist/components/Breakpoint.mjs +4 -0
- package/dist/docs/docs/basics/page.mjs +8 -0
- package/dist/docs/docs/components/DocsLayout.mjs +8 -0
- package/dist/docs/docs/concepts/page.mjs +8 -0
- package/dist/docs/docs/page-files/page.mjs +8 -0
- package/dist/dynamic_page.mjs +7 -5
- package/dist/global.d.ts +5 -1
- package/dist/page_compiler.mjs +203 -57
- package/dist/server/generateHTMLTemplate.d.ts +4 -1
- package/dist/server/generateHTMLTemplate.mjs +7 -5
- package/dist/server/layout.mjs +4 -0
- package/dist/server/server.mjs +7 -5
- package/package.json +2 -2
- package/scripts/bootstrap.js +5 -4
package/dist/build.mjs
CHANGED
|
@@ -266,21 +266,23 @@ var generateHTMLTemplate = async ({
|
|
|
266
266
|
StartTemplate += `<script data-module="true" src="/shipped/${module}.js" defer="true"></script>`;
|
|
267
267
|
}
|
|
268
268
|
if (addPageScriptTag === true) {
|
|
269
|
-
StartTemplate += `<script data-
|
|
269
|
+
StartTemplate += `<script data-page="true" type="module" src="${pageURL === "" ? "" : "/"}${pageURL}/${name}_data.js" defer="true"></script>`;
|
|
270
270
|
}
|
|
271
271
|
StartTemplate += `<script type="module" src="/client.js" defer="true"></script>`;
|
|
272
272
|
let builtHead;
|
|
273
273
|
if (head2.constructor.name === "AsyncFunction") {
|
|
274
|
-
builtHead = await head2(
|
|
274
|
+
builtHead = await head2();
|
|
275
275
|
} else {
|
|
276
|
-
builtHead = head2(
|
|
276
|
+
builtHead = head2();
|
|
277
277
|
}
|
|
278
278
|
let HTMLTemplate = renderRecursively(builtHead);
|
|
279
279
|
if (serverData) {
|
|
280
280
|
HTMLTemplate += serverData;
|
|
281
281
|
}
|
|
282
|
-
|
|
283
|
-
|
|
282
|
+
return {
|
|
283
|
+
internals: StartTemplate,
|
|
284
|
+
builtMetadata: HTMLTemplate
|
|
285
|
+
};
|
|
284
286
|
};
|
|
285
287
|
|
|
286
288
|
// src/server/createState.ts
|
package/dist/client/client.mjs
CHANGED
|
@@ -147,6 +147,7 @@ Object.assign(globalThis, childrenlessElements);
|
|
|
147
147
|
// src/client/client.ts
|
|
148
148
|
console.log("Elegance.JS is loading..");
|
|
149
149
|
if (!globalThis.pd) globalThis.pd = {};
|
|
150
|
+
if (!globalThis.ld) globalThis.ld = {};
|
|
150
151
|
Object.assign(window, {
|
|
151
152
|
observe: (subjects, updateCallback) => {
|
|
152
153
|
return {
|
|
@@ -171,7 +172,6 @@ var pageStringCache = /* @__PURE__ */ new Map();
|
|
|
171
172
|
var loc = window.location;
|
|
172
173
|
var doc = document;
|
|
173
174
|
var cleanupProcedures = [];
|
|
174
|
-
var makeArray = Array.from;
|
|
175
175
|
var sanitizePathname = (pn) => {
|
|
176
176
|
if (!pn.endsWith("/") || pn === "/") return pn;
|
|
177
177
|
return pn.slice(0, -1);
|
|
@@ -199,16 +199,16 @@ var createStateManager = (subjects) => {
|
|
|
199
199
|
destroy: (s) => {
|
|
200
200
|
state.subjects.splice(state.subjects.indexOf(s), 1);
|
|
201
201
|
},
|
|
202
|
+
/**
|
|
203
|
+
Bind is deprecated, but kept as a paramater to not upset legacy code.
|
|
204
|
+
*/
|
|
202
205
|
get: (id, bind) => {
|
|
203
|
-
if (bind) {
|
|
204
|
-
return pd[bind].get(id);
|
|
205
|
-
}
|
|
206
206
|
return state.subjects.find((s) => s.id === id);
|
|
207
207
|
},
|
|
208
|
+
/**
|
|
209
|
+
Bind is deprecated, but kept as a paramater to not upset legacy code.
|
|
210
|
+
*/
|
|
208
211
|
getAll: (refs) => refs?.map((ref) => {
|
|
209
|
-
if (ref.bind) {
|
|
210
|
-
return pd[ref.bind].get(ref.id);
|
|
211
|
-
}
|
|
212
212
|
return state.get(ref.id);
|
|
213
213
|
}),
|
|
214
214
|
observe: (subject, observer, key) => {
|
|
@@ -221,51 +221,24 @@ var createStateManager = (subjects) => {
|
|
|
221
221
|
};
|
|
222
222
|
return state;
|
|
223
223
|
};
|
|
224
|
-
var
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
const pathname = fixedUrl.pathname;
|
|
228
|
-
currentPage = pathname;
|
|
229
|
-
history.replaceState(null, "", fixedUrl.href);
|
|
230
|
-
let pageData = pd[pathname];
|
|
231
|
-
if (pd === void 0) {
|
|
232
|
-
console.error(`%cFailed to load! Missing page data!`, "font-size: 20px; font-weight: 600;");
|
|
224
|
+
var initPageData = (data, currentPage2, previousPage, bindLevel) => {
|
|
225
|
+
if (!data) {
|
|
226
|
+
console.error("Data for page " + currentPage2 + " is null.");
|
|
233
227
|
return;
|
|
234
228
|
}
|
|
235
|
-
;
|
|
236
|
-
console.info(`Loading ${pathname}. Page info follows:`, {
|
|
237
|
-
"Deprecated Keys": deprecatedKeys,
|
|
238
|
-
"New Breakpoints:": newBreakpoints || "(none, initial load)",
|
|
239
|
-
"State": pageData.state,
|
|
240
|
-
"OOA": pageData.ooa,
|
|
241
|
-
"SOA": pageData.soa,
|
|
242
|
-
"Load Hooks": pageData.lh
|
|
243
|
-
});
|
|
244
|
-
for (const [bind, subjects] of Object.entries(pageData.binds || {})) {
|
|
245
|
-
if (!pd[bind]) {
|
|
246
|
-
pd[bind] = createStateManager(subjects);
|
|
247
|
-
continue;
|
|
248
|
-
}
|
|
249
|
-
const stateManager = pd[bind];
|
|
250
|
-
const newSubjects = subjects;
|
|
251
|
-
for (const subject of newSubjects) {
|
|
252
|
-
if (stateManager.get(subject.id)) continue;
|
|
253
|
-
pd[bind].subjects.push(subject);
|
|
254
|
-
}
|
|
255
|
-
}
|
|
256
|
-
let state = pageData.stateManager;
|
|
229
|
+
let state = data?.stateManager;
|
|
257
230
|
if (!state) {
|
|
258
|
-
state = createStateManager(
|
|
259
|
-
|
|
231
|
+
state = createStateManager(data.state || []);
|
|
232
|
+
data.stateManager = state;
|
|
260
233
|
}
|
|
261
234
|
for (const subject of state.subjects) {
|
|
262
235
|
subject.observers = /* @__PURE__ */ new Map();
|
|
263
236
|
}
|
|
264
|
-
for (const ooa of
|
|
237
|
+
for (const ooa of data.ooa || []) {
|
|
265
238
|
const els = doc.querySelectorAll(`[key="${ooa.key}"]`);
|
|
266
239
|
let values = {};
|
|
267
|
-
for (const { id
|
|
268
|
-
const subject = state.get(id
|
|
240
|
+
for (const { id } of ooa.refs) {
|
|
241
|
+
const subject = state.get(id);
|
|
269
242
|
values[subject.id] = subject.value;
|
|
270
243
|
const updateFunction = (value) => {
|
|
271
244
|
values[id] = value;
|
|
@@ -289,9 +262,13 @@ var loadPage = (deprecatedKeys = [], newBreakpoints) => {
|
|
|
289
262
|
}
|
|
290
263
|
}
|
|
291
264
|
}
|
|
292
|
-
for (const soa of
|
|
265
|
+
for (const soa of data.soa || []) {
|
|
293
266
|
const el = doc.querySelector(`[key="${soa.key}"]`);
|
|
294
|
-
|
|
267
|
+
if (!el) {
|
|
268
|
+
console.error("Could not find SOA element for SOA:", soa);
|
|
269
|
+
continue;
|
|
270
|
+
}
|
|
271
|
+
const subject = state.get(soa.id);
|
|
295
272
|
if (typeof subject.value === "function") {
|
|
296
273
|
try {
|
|
297
274
|
el[soa.attribute] = (event) => subject.value(state, event);
|
|
@@ -303,14 +280,10 @@ var loadPage = (deprecatedKeys = [], newBreakpoints) => {
|
|
|
303
280
|
el[soa.attribute] = subject.value;
|
|
304
281
|
}
|
|
305
282
|
}
|
|
306
|
-
const loadHooks =
|
|
283
|
+
const loadHooks = data.lh;
|
|
307
284
|
for (const loadHook of loadHooks || []) {
|
|
308
|
-
const
|
|
309
|
-
if (
|
|
310
|
-
// generateClientPageData makes undefined binds into empty strings
|
|
311
|
-
// so that the page_data.js is *smaller*
|
|
312
|
-
bind !== "" && newBreakpoints && !newBreakpoints.includes(`${bind}`)
|
|
313
|
-
) {
|
|
285
|
+
const wasInScope = previousPage ? previousPage.startsWith(currentPage2) : false;
|
|
286
|
+
if (wasInScope && bindLevel !== 1 /* STRICT */) {
|
|
314
287
|
continue;
|
|
315
288
|
}
|
|
316
289
|
const fn = loadHook.fn;
|
|
@@ -322,7 +295,9 @@ var loadPage = (deprecatedKeys = [], newBreakpoints) => {
|
|
|
322
295
|
if (cleanupFunction2) {
|
|
323
296
|
cleanupProcedures.push({
|
|
324
297
|
cleanupFunction: cleanupFunction2,
|
|
325
|
-
|
|
298
|
+
page: `${currentPage2}`,
|
|
299
|
+
loadHook,
|
|
300
|
+
bindLevel
|
|
326
301
|
});
|
|
327
302
|
}
|
|
328
303
|
});
|
|
@@ -331,7 +306,9 @@ var loadPage = (deprecatedKeys = [], newBreakpoints) => {
|
|
|
331
306
|
if (cleanupFunction) {
|
|
332
307
|
cleanupProcedures.push({
|
|
333
308
|
cleanupFunction,
|
|
334
|
-
|
|
309
|
+
page: `${currentPage2}`,
|
|
310
|
+
loadHook,
|
|
311
|
+
bindLevel
|
|
335
312
|
});
|
|
336
313
|
}
|
|
337
314
|
}
|
|
@@ -340,12 +317,42 @@ var loadPage = (deprecatedKeys = [], newBreakpoints) => {
|
|
|
340
317
|
return;
|
|
341
318
|
}
|
|
342
319
|
}
|
|
320
|
+
};
|
|
321
|
+
var loadPage = (previousPage = null) => {
|
|
322
|
+
const fixedUrl = new URL(loc.href);
|
|
323
|
+
fixedUrl.pathname = sanitizePathname(fixedUrl.pathname);
|
|
324
|
+
const pathname = fixedUrl.pathname;
|
|
325
|
+
currentPage = pathname;
|
|
343
326
|
pageStringCache.set(
|
|
344
327
|
currentPage,
|
|
345
328
|
xmlSerializer.serializeToString(doc)
|
|
346
329
|
);
|
|
330
|
+
history.replaceState(null, "", fixedUrl.href);
|
|
331
|
+
{
|
|
332
|
+
let pageData = pd[pathname];
|
|
333
|
+
if (!pd) {
|
|
334
|
+
console.error(`%cFailed to load! Missing page data!`, "font-size: 20px; font-weight: 600;");
|
|
335
|
+
return;
|
|
336
|
+
}
|
|
337
|
+
;
|
|
338
|
+
initPageData(pageData, currentPage, previousPage, 1 /* STRICT */);
|
|
339
|
+
}
|
|
340
|
+
{
|
|
341
|
+
const parts = window.location.pathname.split("/").filter(Boolean);
|
|
342
|
+
const paths = [
|
|
343
|
+
...parts.map((_, i) => "/" + parts.slice(0, i + 1).join("/")),
|
|
344
|
+
"/"
|
|
345
|
+
];
|
|
346
|
+
for (const path of paths) {
|
|
347
|
+
const data = ld[path];
|
|
348
|
+
if (!data) {
|
|
349
|
+
continue;
|
|
350
|
+
}
|
|
351
|
+
initPageData(data, path, previousPage, 2 /* SCOPED */);
|
|
352
|
+
}
|
|
353
|
+
}
|
|
347
354
|
console.info(
|
|
348
|
-
`Loading finished,
|
|
355
|
+
`Loading finished, cleanupProcedures are currently:`,
|
|
349
356
|
cleanupProcedures
|
|
350
357
|
);
|
|
351
358
|
};
|
|
@@ -354,7 +361,6 @@ var fetchPage = async (targetURL) => {
|
|
|
354
361
|
if (pageStringCache.has(pathname)) {
|
|
355
362
|
return domParser.parseFromString(pageStringCache.get(pathname), "text/html");
|
|
356
363
|
}
|
|
357
|
-
console.info(`Fetching ${pathname}`);
|
|
358
364
|
const res = await fetch(targetURL);
|
|
359
365
|
const newDOM = domParser.parseFromString(await res.text(), "text/html");
|
|
360
366
|
{
|
|
@@ -369,13 +375,23 @@ var fetchPage = async (targetURL) => {
|
|
|
369
375
|
}
|
|
370
376
|
}
|
|
371
377
|
{
|
|
372
|
-
const pageDataScript = newDOM.querySelector('script[data-
|
|
378
|
+
const pageDataScript = newDOM.querySelector('script[data-page="true"]');
|
|
373
379
|
if (!pageDataScript) {
|
|
374
380
|
return;
|
|
375
381
|
}
|
|
376
382
|
if (!pd[pathname]) {
|
|
377
|
-
|
|
378
|
-
|
|
383
|
+
await import(pageDataScript.src);
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
{
|
|
387
|
+
const layoutDataScripts = Array.from(newDOM.querySelectorAll('script[data-layout="true"]'));
|
|
388
|
+
for (const script of layoutDataScripts) {
|
|
389
|
+
const url = new URL(script.src, window.location.origin);
|
|
390
|
+
const dir = url.pathname.substring(0, url.pathname.lastIndexOf("/")) || "/";
|
|
391
|
+
const pathname2 = sanitizePathname(dir);
|
|
392
|
+
if (!ld[pathname2]) {
|
|
393
|
+
await import(script.src);
|
|
394
|
+
}
|
|
379
395
|
}
|
|
380
396
|
}
|
|
381
397
|
pageStringCache.set(pathname, xmlSerializer.serializeToString(newDOM));
|
|
@@ -391,39 +407,9 @@ var navigateLocally = async (target, pushState = true) => {
|
|
|
391
407
|
let newPage = await fetchPage(targetURL);
|
|
392
408
|
if (!newPage) return;
|
|
393
409
|
if (pathname === currentPage) return;
|
|
394
|
-
const curBreaks = makeArray(doc.querySelectorAll("div[bp]"));
|
|
395
|
-
const curBpTags = curBreaks.map((bp) => bp.getAttribute("bp"));
|
|
396
|
-
const newBreaks = makeArray(newPage.querySelectorAll("div[bp]"));
|
|
397
|
-
const newBpTags = newBreaks.map((bp) => bp.getAttribute("bp"));
|
|
398
|
-
const latestMatchingBreakpoints = (arr1, arr2) => {
|
|
399
|
-
let i = 0;
|
|
400
|
-
const len = Math.min(arr1.length, arr2.length);
|
|
401
|
-
while (i < len && arr1[i].getAttribute("bp") === arr2[i].getAttribute("bp")) i++;
|
|
402
|
-
return i > 0 ? [arr1[i - 1], arr2[i - 1]] : [document.body, newPage.body];
|
|
403
|
-
};
|
|
404
|
-
const [oldPageLatest, newPageLatest] = latestMatchingBreakpoints(curBreaks, newBreaks);
|
|
405
|
-
const deprecatedKeys = [];
|
|
406
|
-
const breakpointKey = oldPageLatest.getAttribute("key");
|
|
407
|
-
const getDeprecatedKeysRecursively = (element) => {
|
|
408
|
-
const key = element.getAttribute("key");
|
|
409
|
-
if (key) {
|
|
410
|
-
deprecatedKeys.push(key);
|
|
411
|
-
}
|
|
412
|
-
if (key === breakpointKey || !breakpointKey) return;
|
|
413
|
-
for (const child of makeArray(element.children)) {
|
|
414
|
-
getDeprecatedKeysRecursively(child);
|
|
415
|
-
}
|
|
416
|
-
};
|
|
417
|
-
getDeprecatedKeysRecursively(doc.body);
|
|
418
|
-
const deprecatedBreakpoints = curBpTags.filter(
|
|
419
|
-
(item) => !newBpTags.includes(item)
|
|
420
|
-
);
|
|
421
|
-
const newBreakpoints = newBpTags.filter(
|
|
422
|
-
(item) => !curBpTags.includes(item)
|
|
423
|
-
);
|
|
424
410
|
for (const cleanupProcedure of [...cleanupProcedures]) {
|
|
425
|
-
const
|
|
426
|
-
if (
|
|
411
|
+
const isInScope = pathname.startsWith(cleanupProcedure.page);
|
|
412
|
+
if (!isInScope || cleanupProcedure.bindLevel === 1 /* STRICT */) {
|
|
427
413
|
try {
|
|
428
414
|
cleanupProcedure.cleanupFunction();
|
|
429
415
|
} catch (e) {
|
|
@@ -433,14 +419,32 @@ var navigateLocally = async (target, pushState = true) => {
|
|
|
433
419
|
cleanupProcedures.splice(cleanupProcedures.indexOf(cleanupProcedure), 1);
|
|
434
420
|
}
|
|
435
421
|
}
|
|
422
|
+
let oldPageLatest = doc.body;
|
|
423
|
+
let newPageLatest = newPage.body;
|
|
424
|
+
{
|
|
425
|
+
const newPageLayouts = Array.from(newPage.querySelectorAll("template[layout-id]"));
|
|
426
|
+
const oldPageLayouts = Array.from(doc.querySelectorAll("template[layout-id]"));
|
|
427
|
+
const size = Math.min(newPageLayouts.length, oldPageLayouts.length);
|
|
428
|
+
for (let i = 0; i < size; i++) {
|
|
429
|
+
const newPageLayout = newPageLayouts[i];
|
|
430
|
+
const oldPageLayout = oldPageLayouts[i];
|
|
431
|
+
const newLayoutId = newPageLayout.getAttribute("layout-id");
|
|
432
|
+
const oldLayoutId = oldPageLayout.getAttribute("layout-id");
|
|
433
|
+
if (newLayoutId !== oldLayoutId) {
|
|
434
|
+
break;
|
|
435
|
+
}
|
|
436
|
+
oldPageLatest = oldPageLayout.nextElementSibling;
|
|
437
|
+
newPageLatest = newPageLayout.nextElementSibling;
|
|
438
|
+
}
|
|
439
|
+
}
|
|
436
440
|
oldPageLatest.replaceWith(newPageLatest);
|
|
437
441
|
doc.head.replaceWith(newPage.head);
|
|
438
442
|
if (pushState) history.pushState(null, "", targetURL.href);
|
|
443
|
+
loadPage(currentPage);
|
|
439
444
|
currentPage = pathname;
|
|
440
445
|
if (targetURL.hash) {
|
|
441
446
|
doc.getElementById(targetURL.hash.slice(1))?.scrollIntoView();
|
|
442
447
|
}
|
|
443
|
-
loadPage(deprecatedKeys, newBreakpoints);
|
|
444
448
|
};
|
|
445
449
|
window.onpopstate = async (event) => {
|
|
446
450
|
event.preventDefault();
|
package/dist/client/watcher.mjs
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
// src/client/watcher.ts
|
|
2
2
|
var eventSource = new EventSource(`http://localhost:${watchServerPort}/events`);
|
|
3
|
+
eventSource.onerror = async () => {
|
|
4
|
+
};
|
|
3
5
|
eventSource.onmessage = async (event) => {
|
|
4
|
-
console.log(`hot-reload, command received: ${event.data}`);
|
|
5
6
|
if (event.data === "reload") {
|
|
6
7
|
for (const cleanupProcedure of cleanupProcedures) {
|
|
7
8
|
cleanupProcedure.cleanupFunction();
|
package/dist/compile_docs.mjs
CHANGED
|
@@ -269,21 +269,23 @@ var generateHTMLTemplate = async ({
|
|
|
269
269
|
StartTemplate += `<script data-module="true" src="/shipped/${module}.js" defer="true"></script>`;
|
|
270
270
|
}
|
|
271
271
|
if (addPageScriptTag === true) {
|
|
272
|
-
StartTemplate += `<script data-
|
|
272
|
+
StartTemplate += `<script data-page="true" type="module" src="${pageURL === "" ? "" : "/"}${pageURL}/${name}_data.js" defer="true"></script>`;
|
|
273
273
|
}
|
|
274
274
|
StartTemplate += `<script type="module" src="/client.js" defer="true"></script>`;
|
|
275
275
|
let builtHead;
|
|
276
276
|
if (head2.constructor.name === "AsyncFunction") {
|
|
277
|
-
builtHead = await head2(
|
|
277
|
+
builtHead = await head2();
|
|
278
278
|
} else {
|
|
279
|
-
builtHead = head2(
|
|
279
|
+
builtHead = head2();
|
|
280
280
|
}
|
|
281
281
|
let HTMLTemplate = renderRecursively(builtHead);
|
|
282
282
|
if (serverData) {
|
|
283
283
|
HTMLTemplate += serverData;
|
|
284
284
|
}
|
|
285
|
-
|
|
286
|
-
|
|
285
|
+
return {
|
|
286
|
+
internals: StartTemplate,
|
|
287
|
+
builtMetadata: HTMLTemplate
|
|
288
|
+
};
|
|
287
289
|
};
|
|
288
290
|
|
|
289
291
|
// src/server/createState.ts
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
// src/components/Breakpoint.ts
|
|
2
2
|
var Breakpoint = (options, ...children) => {
|
|
3
|
+
process.emitWarning(
|
|
4
|
+
"Function Breakpoint() is deprecated. Prefer layout.ts files instead.",
|
|
5
|
+
{ type: "DeprecationWarning" }
|
|
6
|
+
);
|
|
3
7
|
if (options.id === void 0) throw `Breakpoints must set a name attribute.`;
|
|
4
8
|
const id = options.id;
|
|
5
9
|
delete options.id;
|
|
@@ -15,6 +15,10 @@ var PageHeading = (title2, id) => h2({
|
|
|
15
15
|
|
|
16
16
|
// src/components/Breakpoint.ts
|
|
17
17
|
var Breakpoint = (options, ...children) => {
|
|
18
|
+
process.emitWarning(
|
|
19
|
+
"Function Breakpoint() is deprecated. Prefer layout.ts files instead.",
|
|
20
|
+
{ type: "DeprecationWarning" }
|
|
21
|
+
);
|
|
18
22
|
if (options.id === void 0) throw `Breakpoints must set a name attribute.`;
|
|
19
23
|
const id = options.id;
|
|
20
24
|
delete options.id;
|
|
@@ -507,6 +511,10 @@ var CodeBlock = (value, parse = true) => div(
|
|
|
507
511
|
// src/server/layout.ts
|
|
508
512
|
if (!globalThis.__SERVER_CURRENT_LAYOUT_ID__) globalThis.__SERVER_CURRENT_LAYOUT_ID__ = 1;
|
|
509
513
|
var createLayout = (name) => {
|
|
514
|
+
process.emitWarning(
|
|
515
|
+
"Function createLayout() is deprecated. Prefer layout.ts files instead.",
|
|
516
|
+
{ type: "DeprecationWarning" }
|
|
517
|
+
);
|
|
510
518
|
const layouts = globalThis.__SERVER_CURRENT_LAYOUTS__;
|
|
511
519
|
if (layouts.has(name)) return layouts.get(name);
|
|
512
520
|
const id = globalThis.__SERVER_CURRENT_LAYOUT_ID__ += 1;
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
// src/components/Breakpoint.ts
|
|
2
2
|
var Breakpoint = (options, ...children) => {
|
|
3
|
+
process.emitWarning(
|
|
4
|
+
"Function Breakpoint() is deprecated. Prefer layout.ts files instead.",
|
|
5
|
+
{ type: "DeprecationWarning" }
|
|
6
|
+
);
|
|
3
7
|
if (options.id === void 0) throw `Breakpoints must set a name attribute.`;
|
|
4
8
|
const id = options.id;
|
|
5
9
|
delete options.id;
|
|
@@ -310,6 +314,10 @@ var Toast = (bind) => {
|
|
|
310
314
|
// src/server/layout.ts
|
|
311
315
|
if (!globalThis.__SERVER_CURRENT_LAYOUT_ID__) globalThis.__SERVER_CURRENT_LAYOUT_ID__ = 1;
|
|
312
316
|
var createLayout = (name) => {
|
|
317
|
+
process.emitWarning(
|
|
318
|
+
"Function createLayout() is deprecated. Prefer layout.ts files instead.",
|
|
319
|
+
{ type: "DeprecationWarning" }
|
|
320
|
+
);
|
|
313
321
|
const layouts = globalThis.__SERVER_CURRENT_LAYOUTS__;
|
|
314
322
|
if (layouts.has(name)) return layouts.get(name);
|
|
315
323
|
const id = globalThis.__SERVER_CURRENT_LAYOUT_ID__ += 1;
|
|
@@ -438,6 +438,10 @@ var CodeBlock = (value, parse = true) => div(
|
|
|
438
438
|
|
|
439
439
|
// src/components/Breakpoint.ts
|
|
440
440
|
var Breakpoint = (options, ...children) => {
|
|
441
|
+
process.emitWarning(
|
|
442
|
+
"Function Breakpoint() is deprecated. Prefer layout.ts files instead.",
|
|
443
|
+
{ type: "DeprecationWarning" }
|
|
444
|
+
);
|
|
441
445
|
if (options.id === void 0) throw `Breakpoints must set a name attribute.`;
|
|
442
446
|
const id = options.id;
|
|
443
447
|
delete options.id;
|
|
@@ -500,6 +504,10 @@ var Header = () => header(
|
|
|
500
504
|
// src/server/layout.ts
|
|
501
505
|
if (!globalThis.__SERVER_CURRENT_LAYOUT_ID__) globalThis.__SERVER_CURRENT_LAYOUT_ID__ = 1;
|
|
502
506
|
var createLayout = (name) => {
|
|
507
|
+
process.emitWarning(
|
|
508
|
+
"Function createLayout() is deprecated. Prefer layout.ts files instead.",
|
|
509
|
+
{ type: "DeprecationWarning" }
|
|
510
|
+
);
|
|
503
511
|
const layouts = globalThis.__SERVER_CURRENT_LAYOUTS__;
|
|
504
512
|
if (layouts.has(name)) return layouts.get(name);
|
|
505
513
|
const id = globalThis.__SERVER_CURRENT_LAYOUT_ID__ += 1;
|
|
@@ -438,6 +438,10 @@ var CodeBlock = (value, parse = true) => div(
|
|
|
438
438
|
|
|
439
439
|
// src/components/Breakpoint.ts
|
|
440
440
|
var Breakpoint = (options, ...children) => {
|
|
441
|
+
process.emitWarning(
|
|
442
|
+
"Function Breakpoint() is deprecated. Prefer layout.ts files instead.",
|
|
443
|
+
{ type: "DeprecationWarning" }
|
|
444
|
+
);
|
|
441
445
|
if (options.id === void 0) throw `Breakpoints must set a name attribute.`;
|
|
442
446
|
const id = options.id;
|
|
443
447
|
delete options.id;
|
|
@@ -500,6 +504,10 @@ var Header = () => header(
|
|
|
500
504
|
// src/server/layout.ts
|
|
501
505
|
if (!globalThis.__SERVER_CURRENT_LAYOUT_ID__) globalThis.__SERVER_CURRENT_LAYOUT_ID__ = 1;
|
|
502
506
|
var createLayout = (name) => {
|
|
507
|
+
process.emitWarning(
|
|
508
|
+
"Function createLayout() is deprecated. Prefer layout.ts files instead.",
|
|
509
|
+
{ type: "DeprecationWarning" }
|
|
510
|
+
);
|
|
503
511
|
const layouts = globalThis.__SERVER_CURRENT_LAYOUTS__;
|
|
504
512
|
if (layouts.has(name)) return layouts.get(name);
|
|
505
513
|
const id = globalThis.__SERVER_CURRENT_LAYOUT_ID__ += 1;
|
package/dist/dynamic_page.mjs
CHANGED
|
@@ -223,21 +223,23 @@ var generateHTMLTemplate = async ({
|
|
|
223
223
|
StartTemplate += `<script data-module="true" src="/shipped/${module}.js" defer="true"></script>`;
|
|
224
224
|
}
|
|
225
225
|
if (addPageScriptTag === true) {
|
|
226
|
-
StartTemplate += `<script data-
|
|
226
|
+
StartTemplate += `<script data-page="true" type="module" src="${pageURL === "" ? "" : "/"}${pageURL}/${name}_data.js" defer="true"></script>`;
|
|
227
227
|
}
|
|
228
228
|
StartTemplate += `<script type="module" src="/client.js" defer="true"></script>`;
|
|
229
229
|
let builtHead;
|
|
230
230
|
if (head2.constructor.name === "AsyncFunction") {
|
|
231
|
-
builtHead = await head2(
|
|
231
|
+
builtHead = await head2();
|
|
232
232
|
} else {
|
|
233
|
-
builtHead = head2(
|
|
233
|
+
builtHead = head2();
|
|
234
234
|
}
|
|
235
235
|
let HTMLTemplate = renderRecursively(builtHead);
|
|
236
236
|
if (serverData) {
|
|
237
237
|
HTMLTemplate += serverData;
|
|
238
238
|
}
|
|
239
|
-
|
|
240
|
-
|
|
239
|
+
return {
|
|
240
|
+
internals: StartTemplate,
|
|
241
|
+
builtMetadata: HTMLTemplate
|
|
242
|
+
};
|
|
241
243
|
};
|
|
242
244
|
|
|
243
245
|
// src/server/createState.ts
|
package/dist/global.d.ts
CHANGED
|
@@ -28,7 +28,8 @@ declare global {
|
|
|
28
28
|
options: Record<string, any> | Child;
|
|
29
29
|
};
|
|
30
30
|
type Page = (AnyBuiltElement) | (() => AnyBuiltElement) | (() => Promise<AnyBuiltElement>);
|
|
31
|
-
type
|
|
31
|
+
type Layout = ((child: Child) => (AnyBuiltElement | Promise<AnyBuiltElement>));
|
|
32
|
+
type Metadata = (() => (AnyBuiltElement)) | (() => Promise<AnyBuiltElement>);
|
|
32
33
|
type ObjectAttribute<T> = T extends ObjectAttributeType.STATE ? {
|
|
33
34
|
type: ObjectAttributeType;
|
|
34
35
|
id: string | number;
|
|
@@ -267,7 +268,10 @@ declare global {
|
|
|
267
268
|
onTransitionEnd?: EleganceEventListener;
|
|
268
269
|
onToggle?: EleganceEventListener;
|
|
269
270
|
}
|
|
271
|
+
/** Generated client-page data. Contains things like loadHooks, state, etc. */
|
|
270
272
|
var pd: Record<string, any>;
|
|
273
|
+
/** Generated layout-data. Contains things like loadHooks, state, etc.*/
|
|
274
|
+
var ld: Record<string, any>;
|
|
271
275
|
var client: {
|
|
272
276
|
navigateLocally: (target: string, pushState?: boolean) => any;
|
|
273
277
|
fetchPage: (targetURL: URL) => Promise<Document | void>;
|
package/dist/page_compiler.mjs
CHANGED
|
@@ -223,21 +223,23 @@ var generateHTMLTemplate = async ({
|
|
|
223
223
|
StartTemplate += `<script data-module="true" src="/shipped/${module}.js" defer="true"></script>`;
|
|
224
224
|
}
|
|
225
225
|
if (addPageScriptTag === true) {
|
|
226
|
-
StartTemplate += `<script data-
|
|
226
|
+
StartTemplate += `<script data-page="true" type="module" src="${pageURL === "" ? "" : "/"}${pageURL}/${name}_data.js" defer="true"></script>`;
|
|
227
227
|
}
|
|
228
228
|
StartTemplate += `<script type="module" src="/client.js" defer="true"></script>`;
|
|
229
229
|
let builtHead;
|
|
230
230
|
if (head2.constructor.name === "AsyncFunction") {
|
|
231
|
-
builtHead = await head2(
|
|
231
|
+
builtHead = await head2();
|
|
232
232
|
} else {
|
|
233
|
-
builtHead = head2(
|
|
233
|
+
builtHead = head2();
|
|
234
234
|
}
|
|
235
235
|
let HTMLTemplate = renderRecursively(builtHead);
|
|
236
236
|
if (serverData) {
|
|
237
237
|
HTMLTemplate += serverData;
|
|
238
238
|
}
|
|
239
|
-
|
|
240
|
-
|
|
239
|
+
return {
|
|
240
|
+
internals: StartTemplate,
|
|
241
|
+
builtMetadata: HTMLTemplate
|
|
242
|
+
};
|
|
241
243
|
};
|
|
242
244
|
|
|
243
245
|
// src/server/createState.ts
|
|
@@ -318,9 +320,7 @@ var getProjectFiles = (pagesDirectory) => {
|
|
|
318
320
|
for (const subdirectory of subdirectories) {
|
|
319
321
|
const absoluteDirectoryPath = path.join(pagesDirectory, subdirectory);
|
|
320
322
|
const subdirectoryFiles = fs.readdirSync(absoluteDirectoryPath, { withFileTypes: true }).filter((f) => f.name.endsWith(".ts"));
|
|
321
|
-
|
|
322
|
-
files.push(file);
|
|
323
|
-
}
|
|
323
|
+
files.push(...subdirectoryFiles);
|
|
324
324
|
}
|
|
325
325
|
return files;
|
|
326
326
|
};
|
|
@@ -518,26 +518,27 @@ ${trace}`);
|
|
|
518
518
|
}
|
|
519
519
|
}
|
|
520
520
|
};
|
|
521
|
-
var
|
|
521
|
+
var pageToHTML = async (pageLocation, pageElements, metadata, DIST_DIR2, pageName, doWrite = true, requiredClientModules = [], layout) => {
|
|
522
522
|
if (typeof pageElements === "string" || typeof pageElements === "boolean" || typeof pageElements === "number" || Array.isArray(pageElements)) {
|
|
523
|
-
|
|
523
|
+
throw new Error(`The root element of a page / layout must be a built element, not just a Child. Received: ${typeof pageElements}.`);
|
|
524
524
|
}
|
|
525
525
|
const objectAttributes = [];
|
|
526
526
|
const stack = [];
|
|
527
527
|
const processedPageElements = processPageElements(pageElements, objectAttributes, 0, stack);
|
|
528
|
-
elementKey = 0;
|
|
529
528
|
const renderedPage = await serverSideRenderPage(
|
|
530
529
|
processedPageElements,
|
|
531
530
|
pageLocation
|
|
532
531
|
);
|
|
533
|
-
const
|
|
532
|
+
const { internals, builtMetadata } = await generateHTMLTemplate({
|
|
534
533
|
pageURL: path.relative(DIST_DIR2, pageLocation),
|
|
535
534
|
head: metadata,
|
|
536
535
|
addPageScriptTag: true,
|
|
537
536
|
name: pageName,
|
|
538
537
|
requiredClientModules
|
|
539
538
|
});
|
|
540
|
-
const
|
|
539
|
+
const headHTML = `<!DOCTYPE html>${layout.metadata.startHTML}${layout.scriptTag}${internals}${builtMetadata}${layout.metadata.endHTML}`;
|
|
540
|
+
const bodyHTML = `${layout.pageContent.startHTML}${renderedPage.bodyHTML}${layout.pageContent.endHTML}`;
|
|
541
|
+
const resultHTML = `${headHTML}${bodyHTML}`;
|
|
541
542
|
const htmlLocation = path.join(pageLocation, (pageName === "page" ? "index" : pageName) + ".html");
|
|
542
543
|
if (doWrite) {
|
|
543
544
|
fs.writeFileSync(
|
|
@@ -556,15 +557,14 @@ var generateSuitablePageElements = async (pageLocation, pageElements, metadata,
|
|
|
556
557
|
};
|
|
557
558
|
}
|
|
558
559
|
};
|
|
559
|
-
var generateClientPageData = async (pageLocation, state, objectAttributes, pageLoadHooks, DIST_DIR2, pageName) => {
|
|
560
|
+
var generateClientPageData = async (pageLocation, state, objectAttributes, pageLoadHooks, DIST_DIR2, pageName, globalVariableName = "pd") => {
|
|
560
561
|
const pageDiff = path.relative(DIST_DIR2, pageLocation);
|
|
561
562
|
let clientPageJSText = `${globalThis.__SERVER_PAGE_DATA_BANNER__}let url="${pageDiff === "" ? "/" : `/${pageDiff}`}";`;
|
|
562
563
|
{
|
|
563
564
|
clientPageJSText += `export const data = {`;
|
|
564
565
|
if (state) {
|
|
565
|
-
const nonBoundState = state.filter((subj) => subj.bind === void 0);
|
|
566
566
|
clientPageJSText += `state:[`;
|
|
567
|
-
for (const subject of
|
|
567
|
+
for (const subject of state) {
|
|
568
568
|
if (typeof subject.value === "string") {
|
|
569
569
|
const stringified = JSON.stringify(subject.value);
|
|
570
570
|
clientPageJSText += `{id:${subject.id},value:${stringified}},`;
|
|
@@ -575,34 +575,6 @@ var generateClientPageData = async (pageLocation, state, objectAttributes, pageL
|
|
|
575
575
|
}
|
|
576
576
|
}
|
|
577
577
|
clientPageJSText += `],`;
|
|
578
|
-
const formattedBoundState = {};
|
|
579
|
-
const stateBinds = state.map((subj) => subj.bind).filter((bind) => bind !== void 0);
|
|
580
|
-
for (const bind of stateBinds) {
|
|
581
|
-
formattedBoundState[bind] = [];
|
|
582
|
-
}
|
|
583
|
-
;
|
|
584
|
-
const boundState = state.filter((subj) => subj.bind !== void 0);
|
|
585
|
-
for (const subject of boundState) {
|
|
586
|
-
const bindingState = formattedBoundState[subject.bind];
|
|
587
|
-
delete subject.bind;
|
|
588
|
-
bindingState.push(subject);
|
|
589
|
-
}
|
|
590
|
-
const bindSubjectPairing = Object.entries(formattedBoundState);
|
|
591
|
-
if (bindSubjectPairing.length > 0) {
|
|
592
|
-
clientPageJSText += "binds:{";
|
|
593
|
-
for (const [bind, subjects] of bindSubjectPairing) {
|
|
594
|
-
clientPageJSText += `${bind}:[`;
|
|
595
|
-
for (const subject of subjects) {
|
|
596
|
-
if (typeof subject.value === "string") {
|
|
597
|
-
clientPageJSText += `{id:${subject.id},value:${JSON.stringify(subject.value)}},`;
|
|
598
|
-
} else {
|
|
599
|
-
clientPageJSText += `{id:${subject.id},value:${JSON.stringify(subject.value)}},`;
|
|
600
|
-
}
|
|
601
|
-
}
|
|
602
|
-
clientPageJSText += "]";
|
|
603
|
-
}
|
|
604
|
-
clientPageJSText += "},";
|
|
605
|
-
}
|
|
606
578
|
}
|
|
607
579
|
const stateObjectAttributes = objectAttributes.filter((oa) => oa.type === 1 /* STATE */);
|
|
608
580
|
if (stateObjectAttributes.length > 0) {
|
|
@@ -620,9 +592,7 @@ var generateClientPageData = async (pageLocation, state, objectAttributes, pageL
|
|
|
620
592
|
observerObjectAttributeString += `{key:${ooa.key},attribute:"${ooa.attribute}",update:${ooa.update.toString()},`;
|
|
621
593
|
observerObjectAttributeString += `refs:[`;
|
|
622
594
|
for (const ref of ooa.refs) {
|
|
623
|
-
observerObjectAttributeString += `{id:${ref.id}
|
|
624
|
-
if (ref.bind !== void 0) observerObjectAttributeString += `,bind:${ref.bind}`;
|
|
625
|
-
observerObjectAttributeString += "},";
|
|
595
|
+
observerObjectAttributeString += `{id:${ref.id}},`;
|
|
626
596
|
}
|
|
627
597
|
observerObjectAttributeString += "]},";
|
|
628
598
|
}
|
|
@@ -632,14 +602,13 @@ var generateClientPageData = async (pageLocation, state, objectAttributes, pageL
|
|
|
632
602
|
if (pageLoadHooks.length > 0) {
|
|
633
603
|
clientPageJSText += "lh:[";
|
|
634
604
|
for (const loadHook of pageLoadHooks) {
|
|
635
|
-
|
|
636
|
-
clientPageJSText += `{fn:${loadHook.fn},bind:"${key || ""}"},`;
|
|
605
|
+
clientPageJSText += `{fn:${loadHook.fn}},`;
|
|
637
606
|
}
|
|
638
607
|
clientPageJSText += "],";
|
|
639
608
|
}
|
|
640
609
|
clientPageJSText += `};`;
|
|
641
610
|
}
|
|
642
|
-
clientPageJSText +=
|
|
611
|
+
clientPageJSText += `if(!globalThis.${globalVariableName}) { globalThis.${globalVariableName} = {}; }; globalThis.${globalVariableName}[url] = data;`;
|
|
643
612
|
const pageDataPath = path.join(pageLocation, `${pageName}_data.js`);
|
|
644
613
|
let sendHardReloadInstruction = false;
|
|
645
614
|
const transformedResult = await esbuild.transform(clientPageJSText, { minify: options.environment === "production" }).catch((error) => {
|
|
@@ -655,6 +624,175 @@ var generateClientPageData = async (pageLocation, state, objectAttributes, pageL
|
|
|
655
624
|
fs.writeFileSync(pageDataPath, transformedResult.code, "utf-8");
|
|
656
625
|
return { sendHardReloadInstruction };
|
|
657
626
|
};
|
|
627
|
+
var generateLayout = async (DIST_DIR2, filePath, childIndicator) => {
|
|
628
|
+
const directory = path.dirname(filePath);
|
|
629
|
+
initializeState();
|
|
630
|
+
initializeObjectAttributes();
|
|
631
|
+
resetLoadHooks();
|
|
632
|
+
globalThis.__SERVER_PAGE_DATA_BANNER__ = "";
|
|
633
|
+
let layoutElements;
|
|
634
|
+
let metadataElements;
|
|
635
|
+
let modules = [];
|
|
636
|
+
try {
|
|
637
|
+
const {
|
|
638
|
+
layout,
|
|
639
|
+
metadata,
|
|
640
|
+
isDynamic,
|
|
641
|
+
requiredClientModules
|
|
642
|
+
} = await import("file://" + filePath);
|
|
643
|
+
if (requiredClientModules !== void 0) {
|
|
644
|
+
modules = requiredClientModules;
|
|
645
|
+
}
|
|
646
|
+
layoutElements = layout;
|
|
647
|
+
metadataElements = metadata;
|
|
648
|
+
if (isDynamic === true) {
|
|
649
|
+
const result = await esbuild.build({
|
|
650
|
+
entryPoints: [filePath],
|
|
651
|
+
bundle: false,
|
|
652
|
+
format: "iife",
|
|
653
|
+
globalName: "__exports",
|
|
654
|
+
write: false,
|
|
655
|
+
platform: "node",
|
|
656
|
+
plugins: [externalPackagesPlugin]
|
|
657
|
+
});
|
|
658
|
+
let iifeCode = result.outputFiles[0].text;
|
|
659
|
+
iifeCode = iifeCode.replace(/^var __exports = /, "");
|
|
660
|
+
const wrappedCode = `import { createRequire } from 'module'; const require = createRequire(import.meta.url);
|
|
661
|
+
|
|
662
|
+
export function construct() {
|
|
663
|
+
${iifeCode}
|
|
664
|
+
return __exports
|
|
665
|
+
}`;
|
|
666
|
+
fs.writeFileSync(filePath, wrappedCode);
|
|
667
|
+
return { pageContentHTML: "", metadataHTML: "" };
|
|
668
|
+
}
|
|
669
|
+
fs.rmSync(filePath, { force: true });
|
|
670
|
+
} catch (e) {
|
|
671
|
+
throw new Error(`Error in Page: ${directory === "" ? "/" : directory}layout.mjs - ${e}`);
|
|
672
|
+
}
|
|
673
|
+
{
|
|
674
|
+
if (!layoutElements) {
|
|
675
|
+
throw new Error(`WARNING: ${filePath} should export a const layout, which is of type (child: Child) => AnyBuiltElement.`);
|
|
676
|
+
}
|
|
677
|
+
if (typeof layoutElements === "function") {
|
|
678
|
+
if (layoutElements.constructor.name === "AsyncFunction") {
|
|
679
|
+
layoutElements = await layoutElements(childIndicator);
|
|
680
|
+
} else {
|
|
681
|
+
layoutElements = layoutElements(childIndicator);
|
|
682
|
+
}
|
|
683
|
+
}
|
|
684
|
+
}
|
|
685
|
+
{
|
|
686
|
+
if (!metadataElements) {
|
|
687
|
+
throw new Error(`WARNING: ${filePath} should export a const layout, which is of type (child: Child) => AnyBuiltElement.`);
|
|
688
|
+
}
|
|
689
|
+
if (typeof metadataElements === "function") {
|
|
690
|
+
if (metadataElements.constructor.name === "AsyncFunction") {
|
|
691
|
+
metadataElements = await metadataElements(childIndicator);
|
|
692
|
+
} else {
|
|
693
|
+
metadataElements = metadataElements(childIndicator);
|
|
694
|
+
}
|
|
695
|
+
}
|
|
696
|
+
}
|
|
697
|
+
const state = getState();
|
|
698
|
+
const pageLoadHooks = getLoadHooks();
|
|
699
|
+
const objectAttributes = getObjectAttributes();
|
|
700
|
+
if (typeof layoutElements === "string" || typeof layoutElements === "boolean" || typeof layoutElements === "number" || Array.isArray(layoutElements)) {
|
|
701
|
+
throw new Error(`The root element of a page / layout must be a built element, not just a Child. Received: ${typeof layoutElements}.`);
|
|
702
|
+
}
|
|
703
|
+
const foundObjectAttributes = [];
|
|
704
|
+
const stack = [];
|
|
705
|
+
const processedPageElements = processPageElements(layoutElements, foundObjectAttributes, 0, stack);
|
|
706
|
+
const renderedPage = await serverSideRenderPage(
|
|
707
|
+
processedPageElements,
|
|
708
|
+
path.dirname(filePath)
|
|
709
|
+
);
|
|
710
|
+
const metadataHTML = metadataElements ? renderRecursively(metadataElements) : "";
|
|
711
|
+
await generateClientPageData(
|
|
712
|
+
path.dirname(filePath),
|
|
713
|
+
state || {},
|
|
714
|
+
[...objectAttributes, ...foundObjectAttributes],
|
|
715
|
+
pageLoadHooks || [],
|
|
716
|
+
DIST_DIR2,
|
|
717
|
+
"layout",
|
|
718
|
+
"ld"
|
|
719
|
+
);
|
|
720
|
+
return { pageContentHTML: renderedPage.bodyHTML, metadataHTML };
|
|
721
|
+
};
|
|
722
|
+
var builtLayouts = /* @__PURE__ */ new Map();
|
|
723
|
+
var buildLayout = async (filePath) => {
|
|
724
|
+
const storedState = globalThis.__SERVER_CURRENT_STATE__;
|
|
725
|
+
const storedObjectAttributes = globalThis.__SERVER_CURRENT_OBJECT_ATTRIBUTES__;
|
|
726
|
+
const storedLoadHooks = globalThis.__SERVER_CURRENT_LOADHOOKS__;
|
|
727
|
+
const storedPageDataBanner = globalThis.__SERVER_PAGE_DATA_BANNER__;
|
|
728
|
+
const id = globalThis.__SERVER_CURRENT_STATE_ID__ += 1;
|
|
729
|
+
const childIndicator = `<template layout-id="${id}"></template>`;
|
|
730
|
+
const { pageContentHTML, metadataHTML } = await generateLayout(
|
|
731
|
+
DIST_DIR,
|
|
732
|
+
filePath,
|
|
733
|
+
childIndicator
|
|
734
|
+
);
|
|
735
|
+
const splitAround = (str, sub) => {
|
|
736
|
+
const i = str.indexOf(sub);
|
|
737
|
+
if (i === -1) throw new Error("substring does not exist in parent string");
|
|
738
|
+
return {
|
|
739
|
+
startHTML: str.substring(0, i),
|
|
740
|
+
endHTML: str.substring(i + sub.length)
|
|
741
|
+
};
|
|
742
|
+
};
|
|
743
|
+
const splitAt = (str, sub) => {
|
|
744
|
+
const i = str.indexOf(sub) + sub.length;
|
|
745
|
+
if (i === -1) throw new Error("substring does not exist in parent string");
|
|
746
|
+
return {
|
|
747
|
+
startHTML: str.substring(0, i),
|
|
748
|
+
endHTML: str.substring(i)
|
|
749
|
+
};
|
|
750
|
+
};
|
|
751
|
+
const pageURL = path.relative(DIST_DIR, path.dirname(filePath));
|
|
752
|
+
globalThis.__SERVER_CURRENT_STATE__ = storedState;
|
|
753
|
+
globalThis.__SERVER_CURRENT_OBJECT_ATTRIBUTES__ = storedObjectAttributes;
|
|
754
|
+
globalThis.__SERVER_CURRENT_LOADHOOKS__ = storedLoadHooks;
|
|
755
|
+
globalThis.__SERVER_PAGE_DATA_BANNER__ = storedPageDataBanner;
|
|
756
|
+
return {
|
|
757
|
+
pageContent: splitAt(pageContentHTML, childIndicator),
|
|
758
|
+
metadata: splitAround(metadataHTML, childIndicator),
|
|
759
|
+
scriptTag: `<script data-layout="true" type="module" src="${pageURL === "" ? "" : "/"}${pageURL}/layout_data.js" defer="true"></script>`
|
|
760
|
+
};
|
|
761
|
+
};
|
|
762
|
+
var fetchPageLayoutHTML = async (dirname) => {
|
|
763
|
+
const relative = path.relative(DIST_DIR, dirname);
|
|
764
|
+
let split = relative.split(path.sep).filter(Boolean);
|
|
765
|
+
split.push("/");
|
|
766
|
+
split.reverse();
|
|
767
|
+
let layouts = [];
|
|
768
|
+
for (const dir of split) {
|
|
769
|
+
const filePath = path.resolve(path.join(DIST_DIR, dir, "layout.mjs"));
|
|
770
|
+
if (builtLayouts.has(filePath)) {
|
|
771
|
+
layouts.push(builtLayouts.get(filePath));
|
|
772
|
+
} else if (fs.existsSync(filePath)) {
|
|
773
|
+
const built = await buildLayout(filePath);
|
|
774
|
+
builtLayouts.set(filePath, built);
|
|
775
|
+
layouts.push(built);
|
|
776
|
+
}
|
|
777
|
+
}
|
|
778
|
+
const pageContent = {
|
|
779
|
+
startHTML: "",
|
|
780
|
+
endHTML: ""
|
|
781
|
+
};
|
|
782
|
+
const metadata = {
|
|
783
|
+
startHTML: "",
|
|
784
|
+
endHTML: ""
|
|
785
|
+
};
|
|
786
|
+
let scriptTags = "";
|
|
787
|
+
for (const layout of layouts) {
|
|
788
|
+
pageContent.startHTML += layout.pageContent.startHTML;
|
|
789
|
+
metadata.startHTML += layout.metadata.startHTML;
|
|
790
|
+
scriptTags += layout.scriptTag;
|
|
791
|
+
pageContent.endHTML += layout.pageContent.endHTML;
|
|
792
|
+
metadata.endHTML += layout.metadata.endHTML;
|
|
793
|
+
}
|
|
794
|
+
return { pageContent, metadata, scriptTag: scriptTags };
|
|
795
|
+
};
|
|
658
796
|
var buildPages = async (DIST_DIR2) => {
|
|
659
797
|
resetLayouts();
|
|
660
798
|
const subdirectories = [...getAllSubdirectories(DIST_DIR2), ""];
|
|
@@ -692,16 +830,21 @@ var buildPage = async (DIST_DIR2, directory, filePath, name) => {
|
|
|
692
830
|
let pageElements;
|
|
693
831
|
let metadata;
|
|
694
832
|
let modules = [];
|
|
833
|
+
let pageIgnoresLayout = false;
|
|
695
834
|
try {
|
|
696
835
|
const {
|
|
697
836
|
page,
|
|
698
837
|
metadata: pageMetadata,
|
|
699
838
|
isDynamicPage,
|
|
700
|
-
requiredClientModules
|
|
839
|
+
requiredClientModules,
|
|
840
|
+
ignoreLayout
|
|
701
841
|
} = await import("file://" + filePath);
|
|
702
842
|
if (requiredClientModules !== void 0) {
|
|
703
843
|
modules = requiredClientModules;
|
|
704
844
|
}
|
|
845
|
+
if (ignoreLayout) {
|
|
846
|
+
pageIgnoresLayout = true;
|
|
847
|
+
}
|
|
705
848
|
pageElements = page;
|
|
706
849
|
metadata = pageMetadata;
|
|
707
850
|
if (isDynamicPage === true) {
|
|
@@ -745,14 +888,16 @@ return __exports
|
|
|
745
888
|
const state = getState();
|
|
746
889
|
const pageLoadHooks = getLoadHooks();
|
|
747
890
|
const objectAttributes = getObjectAttributes();
|
|
748
|
-
const
|
|
891
|
+
const layout = await fetchPageLayoutHTML(path.dirname(filePath));
|
|
892
|
+
const foundObjectAttributes = await pageToHTML(
|
|
749
893
|
path.dirname(filePath),
|
|
750
894
|
pageElements || body(),
|
|
751
895
|
metadata ?? (() => head()),
|
|
752
896
|
DIST_DIR2,
|
|
753
897
|
name,
|
|
754
898
|
true,
|
|
755
|
-
modules
|
|
899
|
+
modules,
|
|
900
|
+
layout
|
|
756
901
|
);
|
|
757
902
|
const {
|
|
758
903
|
sendHardReloadInstruction
|
|
@@ -920,13 +1065,14 @@ var build = async () => {
|
|
|
920
1065
|
minify: true,
|
|
921
1066
|
treeShaking: true
|
|
922
1067
|
});
|
|
923
|
-
log("Built a client module.");
|
|
924
1068
|
}
|
|
925
1069
|
}
|
|
926
1070
|
const pagesTranspiled = performance.now();
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
1071
|
+
let shouldClientHardReload;
|
|
1072
|
+
{
|
|
1073
|
+
const { shouldClientHardReload: doReload } = await buildPages(DIST_DIR);
|
|
1074
|
+
if (doReload) shouldClientHardReload = true;
|
|
1075
|
+
}
|
|
930
1076
|
const pagesBuilt = performance.now();
|
|
931
1077
|
await buildClient(DIST_DIR);
|
|
932
1078
|
const end = performance.now();
|
|
@@ -205,21 +205,23 @@ var generateHTMLTemplate = async ({
|
|
|
205
205
|
StartTemplate += `<script data-module="true" src="/shipped/${module}.js" defer="true"></script>`;
|
|
206
206
|
}
|
|
207
207
|
if (addPageScriptTag === true) {
|
|
208
|
-
StartTemplate += `<script data-
|
|
208
|
+
StartTemplate += `<script data-page="true" type="module" src="${pageURL === "" ? "" : "/"}${pageURL}/${name}_data.js" defer="true"></script>`;
|
|
209
209
|
}
|
|
210
210
|
StartTemplate += `<script type="module" src="/client.js" defer="true"></script>`;
|
|
211
211
|
let builtHead;
|
|
212
212
|
if (head.constructor.name === "AsyncFunction") {
|
|
213
|
-
builtHead = await head(
|
|
213
|
+
builtHead = await head();
|
|
214
214
|
} else {
|
|
215
|
-
builtHead = head(
|
|
215
|
+
builtHead = head();
|
|
216
216
|
}
|
|
217
217
|
let HTMLTemplate = renderRecursively(builtHead);
|
|
218
218
|
if (serverData) {
|
|
219
219
|
HTMLTemplate += serverData;
|
|
220
220
|
}
|
|
221
|
-
|
|
222
|
-
|
|
221
|
+
return {
|
|
222
|
+
internals: StartTemplate,
|
|
223
|
+
builtMetadata: HTMLTemplate
|
|
224
|
+
};
|
|
223
225
|
};
|
|
224
226
|
export {
|
|
225
227
|
generateHTMLTemplate
|
package/dist/server/layout.mjs
CHANGED
|
@@ -3,6 +3,10 @@ var resetLayouts = () => globalThis.__SERVER_CURRENT_LAYOUTS__ = /* @__PURE__ */
|
|
|
3
3
|
var getLayouts = () => globalThis.__SERVER_CURRENT_LAYOUTS__;
|
|
4
4
|
if (!globalThis.__SERVER_CURRENT_LAYOUT_ID__) globalThis.__SERVER_CURRENT_LAYOUT_ID__ = 1;
|
|
5
5
|
var createLayout = (name) => {
|
|
6
|
+
process.emitWarning(
|
|
7
|
+
"Function createLayout() is deprecated. Prefer layout.ts files instead.",
|
|
8
|
+
{ type: "DeprecationWarning" }
|
|
9
|
+
);
|
|
6
10
|
const layouts = globalThis.__SERVER_CURRENT_LAYOUTS__;
|
|
7
11
|
if (layouts.has(name)) return layouts.get(name);
|
|
8
12
|
const id = globalThis.__SERVER_CURRENT_LAYOUT_ID__ += 1;
|
package/dist/server/server.mjs
CHANGED
|
@@ -223,21 +223,23 @@ var generateHTMLTemplate = async ({
|
|
|
223
223
|
StartTemplate += `<script data-module="true" src="/shipped/${module}.js" defer="true"></script>`;
|
|
224
224
|
}
|
|
225
225
|
if (addPageScriptTag === true) {
|
|
226
|
-
StartTemplate += `<script data-
|
|
226
|
+
StartTemplate += `<script data-page="true" type="module" src="${pageURL === "" ? "" : "/"}${pageURL}/${name}_data.js" defer="true"></script>`;
|
|
227
227
|
}
|
|
228
228
|
StartTemplate += `<script type="module" src="/client.js" defer="true"></script>`;
|
|
229
229
|
let builtHead;
|
|
230
230
|
if (head2.constructor.name === "AsyncFunction") {
|
|
231
|
-
builtHead = await head2(
|
|
231
|
+
builtHead = await head2();
|
|
232
232
|
} else {
|
|
233
|
-
builtHead = head2(
|
|
233
|
+
builtHead = head2();
|
|
234
234
|
}
|
|
235
235
|
let HTMLTemplate = renderRecursively(builtHead);
|
|
236
236
|
if (serverData) {
|
|
237
237
|
HTMLTemplate += serverData;
|
|
238
238
|
}
|
|
239
|
-
|
|
240
|
-
|
|
239
|
+
return {
|
|
240
|
+
internals: StartTemplate,
|
|
241
|
+
builtMetadata: HTMLTemplate
|
|
242
|
+
};
|
|
241
243
|
};
|
|
242
244
|
|
|
243
245
|
// src/server/createState.ts
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "elegance-js",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.17.0",
|
|
4
4
|
"description": "Web-Framework",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
"build": "esbuild --format=esm --platform=node --bundle --outdir=./dist --platform=node --external:esbuild --out-extension:.js=.mjs \"./src/**/*.ts\" && tsc",
|
|
14
14
|
"compile-docs": "node ./dist/compile_docs.mjs --environment=development",
|
|
15
15
|
"compile-docs-bun": "bun run ./dist/compile_docs.mjs --environment=development",
|
|
16
|
-
"prepare": "npm run build
|
|
16
|
+
"prepare": "npm run build"
|
|
17
17
|
},
|
|
18
18
|
"exports": {
|
|
19
19
|
".": {
|
package/scripts/bootstrap.js
CHANGED
|
@@ -299,13 +299,14 @@ const tsconfigContent = JSON.stringify({
|
|
|
299
299
|
esModuleInterop: true,
|
|
300
300
|
forceConsistentCasingInFileNames: true,
|
|
301
301
|
skipLibCheck: true,
|
|
302
|
+
paths: {
|
|
303
|
+
"@/": ["./"],
|
|
304
|
+
}
|
|
305
|
+
|
|
302
306
|
},
|
|
303
307
|
include: ["pages/**/*", "env.d.ts"],
|
|
304
308
|
exclude: ["node_modules"],
|
|
305
|
-
|
|
306
|
-
"@/": ["./"],
|
|
307
|
-
}
|
|
308
|
-
}, null, 2);
|
|
309
|
+
}, null, 4);
|
|
309
310
|
|
|
310
311
|
const indexCssContent = `
|
|
311
312
|
@import url('https://fonts.googleapis.com/css2?family=Inter:ital,opsz,wght@0,14..32,100..900;1,14..32,100..900&display=swap');
|