-
Notifications
You must be signed in to change notification settings - Fork 0
๐ฆ Loading Resources
In ccmjs, resources are treated as declarative dependencies that are resolved at runtime. Resource loading follows the same dependency model that is used for components and datasets.
ccm.load() is the low-level service that powers this mechanism and can also be used directly.
Examples:
const data = await ccm.load('data.json'); // {"foo":"bar"}Load multiple resources:
const results = await ccm.load('data.json', 'hello.html'); // [{"foo":"bar"}, "Hello, world!"]ccm.load( ...resources ) โ Promise<any>Parameters:
-
...resourcesโ One or more resources to load (URLs or resource objects).
Resources can be provided individually or nested in arrays to control parallel and sequential loading.
Returns:
A Promise that
- resolves when all resources load successfully
- rejects when at least one resource fails
- resolves/rejects with either a single value or an array of values/errors
If at least one resource fails, the Promise is rejected โ but all resources are still attempted to be loaded. This means:
- Successful resources appear normally in the result array.
- Failed resources appear at their corresponding index as an Error object.
- The Promise rejects with the entire result array, allowing detailed inspection.
- The order of results always matches the order of the input resources.
The parallel and sequential loading can be flexibly controlled as deep as desired. Each array level alternates between parallel and sequential execution. Top-level entries are loaded in parallel. Each nested array switches the execution mode.
Example:
ccm.load(
'hello.html', // Array Level 0: Parallel
[
'style.css', // Array Level 1: Sequential
'image.png',
[
'data.json', // Array Level 2: Parallel
'script.js'
],
'logo.gif'
],
'picture.jpg'
);The example loads the resources in the following timeline:
| Resource | Timeline |
|---|---|
hello.html |
******------------------ |
style.css |
******------------------ |
image.png |
------******------------ |
data.json |
------------******------ |
script.js |
------------******------ |
logo.gif |
------------------****** |
picture.jpg |
******------------------ |
Instead of a string, a resource may also be passed as an object.
Example:
ccm.load({ url: 'script.js', type: 'module' });Configurable Properties:
| Property | Type | Description | Applies to resource types |
|---|---|---|---|
| url | string | Required. URL of the resource. | |
| type | string | Explicit resource type ('css', 'image', 'js', 'module', 'json', 'xml'). If omitted, the type is inferred from the file extension. Unknown extensions default to 'json'. |
|
| context | Element | DOM context into which the resource will be loaded (default: <head>). |
css, js |
| attr | object | HTML attributes to apply to the generated <link>/<script> tag. |
css, js |
| params | object | HTTP GET/POST parameters to send. | json |
ccm.load() can load resources directly into a Shadow DOM.
To do so, pass the shadow root as the context property of the resource object.
Example:
const host = document.createElement('div');
const root = host.attachShadow({ mode: 'open' });
ccm.load({
url: 'styles.css',
context: root // the <link> element will be appended here
});If a ccmjs instance is passed as context, the resource is automatically loaded into the instanceโs Shadow DOM root.
const instance = await ccm.instance( 'ccm.quiz.js' );
ccm.load({
url: 'styles.css',
context: instance
});ccm.load() can be used to preload image files.
This helps ensure that images can be displayed without delay when they are needed.
All common web image formats are supported, including PNG, JPEG, SVG, WebP, and AVIF.
ccm.load() supports loading CSS and JavaScript files with Subresource Integrity (SRI).
Example:
ccm.load({
url: 'script.js',
attr: {
integrity: 'sha256-47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=',
crossorigin: 'anonymous'
}
});The <head> then contains:
<script src="script.js"
integrity="sha256-47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU="
crossorigin="anonymous"></script>ccm.load() also supports SRI when loading JavaScript modules:
const exports = await ccm.load({
url: 'script.js',
type: 'module',
attr: {
integrity: 'sha384-HUXdHqTt4miSLn4X4gaWsM8XlJuzTYeaIeI23MDnpjnUW2vRxWiDnG4XZBM49Vs9',
crossorigin: 'anonymous'
}
});Behind the scenes, module files are first fetched and verified against the SRI hash. Only if the hash matches, the verified source code is executed as a module (via a Blob URL), without a second network request.
When loading ES modules with ccm.load(), it is possible to request specific exports instead of the entire module object.
This is done by appending one or more hash fragments (#) to the module URL.
Example:
const data = await ccm.load('module.mjs#data');Note: When loading specific module exports (e.g. module.mjs#data), the browser still downloads the entire module file. The export selection happens client-side after the module has been imported. This mechanism improves dependency clarity and configuration expressiveness, but it does not reduce the network transfer size.
You can also access nested properties using dot notation:
const value = await ccm.load('module.mjs#data.foo');This returns the property foo of the exported object data.
Multiple exports can be requested by adding additional hash fragments:
const result = await ccm.load('module.mjs#data#name');Result:
{
data: { ... },
name: "John"
}This mechanism is particularly useful for declaring dependencies on specific functions:
{
mapper: [ "ccm.load", "./mapper.mjs#json2json" ]
}The property mapper will contain the exported function json2json.
This enables fine-grained declarative dependencies inside ccmjs configurations.
In ccmjs, dependencies are not limited to resources, components, or data โ functions can also be injected declaratively.
When loading data, ccm.load() internally calls the browserโs Fetch API.
The value of resource.url becomes the fetch URL, and the remaining fields of the resource object are passed to fetch() as the init object.
The returned value depends on the response content type and is automatically parsed as JSON when possible.
Example transformation:
ccm.load({
url: 'https://example.com/api/user',
method: 'POST',
headers: { 'Content-Type': 'application/json' },
params: { name: 'Mika' }
});becomes:
fetch('https://example.com/api/user', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: '{"name":"Mika"}'
});ccm.load() supports loading XML files.
When the resource type is 'xml' (either detected from the file extension or set explicitly), the result is parsed as XML and returned as a DOM Document object.
Example:
const xml = await ccm.load( 'config.xml' );
console.log( xml instanceof Document ); // true
console.log( xml.querySelector('title')?.textContent );ccm.load() uses fetch() internally, reads the response as text, and parses it via the browserโs XML parser (DOMParser). The resulting Document behaves like any other XML DOM document: elements can be queried, modified, and traversed.
Unlike fetch(), ccm.load()
- integrates directly into CCMโs declarative dependency system,
- supports structured parallel/sequential resolution,
- automatically injects resources into DOM or Shadow DOM contexts,
- and provides built-in support for SRI, and XML parsing.