Page Menu
Home
Sealhub
Search
Configure Global Search
Log In
Files
F8922262
jdd.ts
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
5 KB
Referenced Files
None
Subscribers
None
jdd.ts
View Options
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
);
}
})
.
join
(
" "
);
}
countWords
(
registry
:
Registry
)
:
number
{
return
this
.
parsed
.
value
.
reduce
((
acc
,
{
component_name
,
args
})
=>
{
const
component
=
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/html
Expires
Sat, Sep 20, 14:26 (1 d, 13 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
949272
Default Alt Text
jdd.ts (5 KB)
Attached To
Mode
rJDD jdd
Attached
Detach File
Event Timeline
Log In to Comment