
Product
Rust Support Now in Beta
Socket's Rust support is moving to Beta: all users can scan Cargo projects and generate SBOMs, including Cargo.toml-only crates, with Rust-aware supply chain checks.
@basementuniverse/content-manager
Advanced tools
A component for loading content assets and providing access to them
A component for loading content assets and providing access to them.
npm install @basementuniverse/content-manager
Initialise the content manager before use:
import ContentManager from '@basementuniverse/content-manager';
ContentManager.initialise();
Load content assets:
ContentManager.load([
{
name: 'my-item-1',
type: 'json',
args: ['https://some-url.com/test.json'],
},
]);
Note: when using the "json" or "text" loaders, the argument can either be a URL to the content or the content itself. For example:
ContentManager.load([
{
name: 'my-item-1',
type: 'json',
args: [{ a: 1 }],
},
]);
Check content manager progress and status:
console.log(ContentManager.progress); // a number between 0 (nothing loaded yet) and 1 (finished loading)
console.log(ContentManager.status); // 0: Idle, 1: Loading, 2: Processing, 3: Ready
Fetch a content asset:
const item = ContentManager.get('my-item-1');
const options = { ... };
ContentManager.initialise(options);
Option | Type | Default | Description |
---|---|---|---|
loaders | ContentLoaderMap | (see below) | A dictionary of content loader functions |
processors | ContentProcessorMap | (see below) | A dictionary of content processor functions |
simulateSlowLoading | boolean | false | If true, simulate long loading times |
slowLoadingTimeMin | number | 1000 | Minimum simulated loading time in ms |
slowLoadingTimeMax | number | 3000 | Maximum simulated loading time in ms |
simulateSlowProcessing | boolean | false | If true, simulate long processing times |
slowProcessingTimeMin | number | 1000 | Minimum simulated processing time in ms |
slowProcessingTimeMax | number | 3000 | Maximum simulated processing time in ms |
throwOnNotFound | boolean | false | Throw an error when an unknown content item is fetched with get() |
A loader is a function which takes some arguments (as defined in the content list which is passed to ContentManager.load
, as mentioned above) and returns some kind of content asset.
type ContentLoader = <T>(...args: any[]) => Promise<T>;
Some basic loaders are provided by default:
{
"json": JSONLoader, // Loads JSON (either inline or from a URL)
"font": FontLoader, // Loads a font from a URL and returns a FontFace
"image": ImageLoader, // Loads an image from a URL and returns an HTMLImageElement
"audio": AudioLoader, // Loads an audio file from a URL and returns an HTMLAudioElement
"text": TextLoader, // Loads text (either inline or from a URL)
}
Define a function with a signature that matches ContentLoader
:
import { ContentLoader } from '@basementuniverse/content-manager';
export const MyCustomLoader: ContentLoader = async <HTMLImageElement>(
url: string
): Promise<HTMLImageElement> => {
return new Promise<HTMLImageElement>((resolve, reject) => {
const image = new Image();
image.src = url;
image.addEventListener('load', () => {
resolve(image as any);
});
image.addEventListener('error', () => {
reject(`Error loading image "${url}"`);
});
});
};
Register the loader when initialising the content manager:
ContentManager.initialise({
loaders: {
custom: MyCustomLoader,
},
});
Note: the key (in this example: custom
) is the name of the loader.
Load content assets using the custom loader:
ContentManager.load([
{
name: 'my-custom-item-1',
type: 'custom',
args: ['./test.png'],
},
]);
A processor is a function which takes the full list of loaded content, the current content item being processed, and some optional arguments. This function might mutate the content item or add new content items to the list.
Processor functions are run after all content items have been loaded.
This could be useful for post-processing, e.g. chopping up a texture atlas into multiple textures, unpacking compressed data, or linking together multiple content items into a data structure, etc.
export type ContentProcessor = <T = any>(
content: Record<string, ContentItem>,
item: ContentItem<T>,
...args: any[]
) => Promise<void>;
Define a function with a signature that matches ContentProcessor
:
import { ContentProcessor } from '@basementuniverse/content-manager';
export const MyCustomProcessor: ContentProcessor = async (
content,
item
): Promise<void> => {
// Do some processing here...
// We can modify `content` (e.g. by adding/removing/changing items)
// We can also modify `item` (e.g. by swapping out `item.content`)
};
Register the processor when initialising the content manager:
ContentManager.initialise({
processors: {
custom: MyCustomProcessor,
},
});
Note: the key (in this example: custom
) is the name of the processor.
Load content assets and process them using the custom processor:
ContentManager.load([
{
name: 'my-custom-item-1',
type: 'image',
args: ['./test.png'],
processors: [
{
name: 'custom',
args: [], // Optional, will be passed to the processor as the 3rd+ args
},
],
},
]);
A processor is provided which converts fields in JSON content objects which contain image names into actual image objects. The image names refer to content items which have been loaded with the image
loader.
By default the processor recursively searches for fields called imageName
and replaces them with fields called image
, however this is configurable.
Example:
content.json
:
[
{
"name": "sky",
"type": "image",
"args": ["./sky.png"]
},
{
"name": "tree",
"type": "image",
"args": ["./tree.png"]
},
{
"name": "level-data",
"type": "json",
"args": [
{
"background": {
"imageName": "sky",
"position": [0, 0]
},
"objects": [
{
"imageName": "tree",
"position": [100, 100]
},
{
"imageName": "tree",
"position": [200, 100]
}
]
}
],
"processors": [
{
"name": "imageName",
"args": [
{
"imageNameFieldName": "imageName",
"imageFieldName": "image"
}
]
}
]
}
]
Note: the args provided to the processor are optional. In the example above we have explicitly defined the field names to show how it's done, but if omitted the processor will default to these values anyway.
Then we initialise the content manager and start loading content:
import * as content from './content.json';
ContentManager.initialise();
ContentManager.load(content);
This should result in the following content items being available:
const skyImage = ContentManager.get('sky'); // HTMLImageElement
const treeImage = ContentManager.get('tree'); // HTMLImageElement
const levelData = ContentManager.get('level-data');
// {
// background: {
// image: HTMLImageElement, <-- the 'sky' content item
// position: [0, 0],
// },
// objects: [
// {
// image: HTMLImageElement, <-- the 'tree' content item
// position: [100, 100],
// },
// {
// image: HTMLImageElement, <-- the 'tree' content item
// position: [200, 100],
// },
// ],
// }
A utility script is provided for compiling and minifying content.
ts-node compile-content.ts -i 'content.json' -o 'content-compiled.json'
This script will:
content.json
)text
/json
items which have a file path or URL as their first argumentFAQs
A component for loading content assets and providing access to them
We found that @basementuniverse/content-manager demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Product
Socket's Rust support is moving to Beta: all users can scan Cargo projects and generate SBOMs, including Cargo.toml-only crates, with Rust-aware supply chain checks.
Product
Socket Fix 2.0 brings targeted CVE remediation, smarter upgrade planning, and broader ecosystem support to help developers get to zero alerts.
Security News
Socket CEO Feross Aboukhadijeh joins Risky Business Weekly to unpack recent npm phishing attacks, their limited impact, and the risks if attackers get smarter.