Page Menu
Home
Sealhub
Search
Configure Global Search
Log In
Files
F969866
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
7 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/package.json b/package.json
index 3e1085e..81b3f0a 100644
--- a/package.json
+++ b/package.json
@@ -1,60 +1,60 @@
{
"name": "@sealcode/jdd",
- "version": "0.6.0-alpha4",
+ "version": "0.6.0-alpha5",
"description": "JSON-Driven Documents",
"main": "lib/index.js",
"type": "module",
"scripts": {
"pretest": "npm run build",
"test": "node test.cjs",
"prebuild": "npm run lint",
"build": "tsc",
"typecheck": "tsc --noemit",
"prepare": "npm run build",
"lint": "eslint src",
"preinstrument": "npm run build && rm -fr .xunit coverage lib-instrumented",
"instrument": "npx nyc instrument --exclude \"\" lib lib-instrumented",
"pretest-reports": "npm run instrument",
"test-reports": "npx nyc --exclude \"\" ./node_modules/.bin/mocha --recursive --timeout=10000 --require source-map-support/register --reporter xunit --reporter-option output=.xunit 'lib-instrumented/**/*.test.js' && nyc report --reporter clover --exclude \"\"",
"precover-html": "rm -rf coverate/lcov-report",
"cover-html": "npm run test-reports && nyc report --reporter lcov --exclude \"\" && xdg-open coverage/lcov-report/index.html"
},
"author": "",
"license": "ISC",
"devDependencies": {
"@types/mocha": "^10.0.1",
"@types/prettier": "^2.7.0",
"@types/slug": "^5.0.9",
"@types/uuid": "^9.0.8",
"@typescript-eslint/eslint-plugin": "^5.58.0",
"@typescript-eslint/parser": "^5.58.0",
"assert": "^2.0.0",
"eslint": "^8.38.0",
"eslint-config-prettier": "^8.8.0",
"eslint-plugin-prettier": "^4.2.1",
"eslint-plugin-with-tsc-error": "^0.0.8",
"mocha": "^10.2.0",
"nyc": "^15.1.0",
"source-map-support": "^0.5.21",
"ts-node": "^10.9.1",
"typescript": "^5.0.4"
},
"types": "./@types/index.d.ts",
"dependencies": {
"@sealcode/file-manager": "^1.0.2",
"@sealcode/ts-predicates": "^0.5.3",
"escape-goat": "^4.0.0",
"hyphenopoly": "^5.3.0",
"koa-responsive-image-router": "^0.2.29",
"locreq": "^3.0.0",
"marked": "^12.0.0",
"mri": "^1.2.0",
"prettier": "^2.7.1",
"slug": "^9.1.0",
"tempstream": "^0.4.1",
"uuid": "^9.0.1"
},
"peerDependencies": {
"sealious": "^0.19.18"
}
}
diff --git a/src/jdd.ts b/src/jdd.ts
index 9b17d1a..e27c000 100644
--- a/src/jdd.ts
+++ b/src/jdd.ts
@@ -1,216 +1,216 @@
import { tempstream } from "tempstream";
import { JDDContext } from "./jdd-context.js";
import { Registry } from "./registry.js";
import { EarlyAsset, JDDHeading } from "./component.js";
import { hasField } from "@sealcode/ts-predicates";
import {
JDDocumentContainer,
RawJDDocument,
documentContainerFromParsed,
documentContainerFromStorage,
} from "./document.js";
import { documentToParsed } from "./document.js";
export class JDD {
constructor(
public registry: Registry,
public jdd_context: JDDContext,
public parsed: JDDocumentContainer<"parsed">
) {}
static async fromStorage(
registry: Registry,
jdd_context: JDDContext,
document: RawJDDocument
) {
const parsed = await documentToParsed(
registry,
jdd_context,
documentContainerFromStorage(document)
);
return new JDD(registry, jdd_context, parsed);
}
static fromParsed(
registry: Registry,
jdd_context: JDDContext,
parsed: RawJDDocument
) {
return new JDD(
registry,
jdd_context,
documentContainerFromParsed(parsed)
);
}
render(
make_component_classes = (index: number) => [
"jdd-component",
`component-number-${index}`,
]
) {
return tempstream`${this.parsed.value.map(
({ component_name, args }, index) => {
const component = this.registry.get(component_name);
if (!component) {
console.warn(
"Component not found in the registry: " + component_name
);
return "";
}
for (const arg_name in component?.getArguments()) {
if (!Object.prototype.hasOwnProperty.call(args, arg_name)) {
args[arg_name] = component
?.getArguments()
[arg_name]?.getEmptyValue(this.jdd_context);
}
}
return component.toHTML({
args,
classes: make_component_classes(index),
jdd_context: this.jdd_context,
index,
});
}
)}`;
}
renderEarlyScript(asset: EarlyAsset): string {
if (hasField("url", asset)) {
return /* HTML */ `<script
async
src="${asset.url}"
onLoad="document.dispatchEvent(new Event('loaded-${asset.identity}'))"
${(asset.integrity &&
`integrity="${asset.integrity}" crossorigin="anonymous"`) ||
""}
></script>`;
} else {
return /* HTML */ `<script><${asset.content}/script>`;
}
}
renderEarlyStyle(asset: EarlyAsset): string {
if (hasField("url", asset)) {
const integrity =
(asset.integrity &&
`integrity="${asset.integrity}" crossorigin="anonymous"`) ||
"";
// see https://web.dev/articles/defer-non-critical-css
return /* HTML */ `<link
rel="preload"
href="${asset.url}"
as="style"
onload="this.onload=null;this.rel='stylesheet'"
${integrity}
/>
<noscript
><link rel="stylesheet" href="${asset.url}" ${integrity}
/></noscript>`;
} else {
return /* HTML */ `<style>
${asset.content}
</style>`;
}
}
async renderEarlyAssets() {
const early_assets = (
await Promise.all(
this.parsed.value.map(async ({ component_name, args }) => {
const component = this.registry.get(component_name);
if (!component) {
console.warn(
"Component not found in the registry: " +
component_name
);
return [];
}
for (const arg_name in component?.getArguments()) {
if (
!Object.prototype.hasOwnProperty.call(
args,
arg_name
)
) {
args[arg_name] = component
?.getArguments()
[arg_name]?.getEmptyValue(this.jdd_context);
}
}
return await component.getEarlyAssets(
args,
this.jdd_context
);
})
)
).flat();
const deduplicated_assets: Record<string, EarlyAsset> = {};
for (const asset of early_assets) {
deduplicated_assets[asset.identity] = asset;
}
return Object.values(deduplicated_assets)
.map((asset) => {
if (asset.type == "script") {
return this.renderEarlyScript(asset);
} else if (asset.type == "style") {
- this.renderEarlyStyle(asset);
+ return this.renderEarlyStyle(asset);
}
})
.join(" ");
}
countWords(): number {
return this.parsed.value.reduce((acc, { component_name, args }) => {
const component = this.registry.get(component_name);
if (!component) {
console.warn(
"Component not found in the registry: " + component_name
);
return acc + 0;
}
return acc + component.countWords(args);
}, 0);
}
getHeadings(): JDDHeading[] {
return this.parsed.value
.map(({ component_name, args }) => {
const component = this.registry.get(component_name);
if (!component) {
return [];
}
return component.getHeadings(this.jdd_context, args);
})
.flat();
}
static async renderFromStorage(
registry: Registry,
document: RawJDDocument,
jdd_context: JDDContext
) {
const jdd = await JDD.fromStorage(registry, jdd_context, document);
return jdd.render();
}
static async renderEarlyAssetsFromStorage(
registry: Registry,
document: RawJDDocument,
jdd_context: JDDContext
) {
const jdd = await JDD.fromStorage(registry, jdd_context, document);
return jdd.renderEarlyAssets();
}
static async render(
registry: Registry,
parsed: JDDocumentContainer<"parsed">,
jdd_context: JDDContext
) {
const jdd = new JDD(registry, jdd_context, parsed);
return jdd.render();
}
}
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Sun, Nov 24, 01:56 (22 h, 50 s)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
548072
Default Alt Text
(7 KB)
Attached To
Mode
R130 jdd
Attached
Detach File
Event Timeline
Log In to Comment