Assets
(Some classes in the WebSDK do hold an asset member, which is an object responsible for handling files. An asset is an interface that provides access to its components (also commonly referred to as files). Through the asset interface, the WebSDK can request a files content as blobs or the location (url) of a file where it is publicly available.
Here are some public implementations of the IAsset
interface:
StaticAsset
LocalStorageAsset
Each of them serves a different use case when handling files. If you are working with the SDK externally you will mostly only use the StaticAsset
, but it might be that you encounter / need the other two in special cases.
Storing an asset
Sometimes you want to preserve an asset, so that you do not have to do an expensive computation via the compute server over and over again (e.g. persisting a personalised mannequin). You most likely want to store it on your blob storage or S3 bucket.
To get all components of an asset, iterate over all available asset keys. From there you can call your own storage interface implementation to store the resulting blobs.
It's important that the information of the asset key is not lost. If we later recreate the asset, getComponentKey(key) must be able to resolve to the same exact asset component!
const assetKeys = await asset.getKeys();
for (const assetKey of assetKeys) {
const component = await asset.getComponent(assetKey);
myStorage.store(assetKey, component);
}
Let’s say our myStorage.store(assetKey, component)
stores every blob with a filename that equals its assetKey
in some blob storage. Imagine it being myBlobStorage://assets/avatar-1/*
.
In this case we can recreate the asset later via a StaticAsset:
const myAsset = new StaticAsset("myBlobStorage://assets/avatar-1");
Advanced static assets
In some cases it is not as simple as uploading a bunch of files to a remote folder. In this case the StaticAsset
constructor can also take a custom IResourceProvider
implementation.
Inside your resource provider implementation you can handle things like: Authentication, complex asset component path resolutions or API calls.
Let’s say we got this fictional IResourceProvider
implementation:
type APIServicePictofitAsset {
uid: string,
componentUids: Array<string>,
}
type APIServiceFileDto = {
uid: string,
fileUrl: string,
assetComponentKey: string
}
class MyCustomResourceProvider implements IResourceProvider {
private _user: User;
constructor(myUser: User) {
this._user = myUser;
}
async requestURL(key: string, baseURL: string): Promise<string> {
const apiService = new MyAPIService(this._user.getUUID(), this._user.getToken())
apiService.auth()
const assetDto = apiService.getPictofitAsset(baseURL) as APIServicePictofitAsset;
const assetComponent = assetDto.componentUids.find((it) => it.assetComponentKey === key);
const assetComponentDto = apiService.getPictofitAssetComponent(assetComponent.uid);
return assetComponentDto.fileUrl;
}
}
This is how an authenticated call to our CMS api might look like to access a file stored under a users profile.
If we then want to use this custom IResourceProvider
in our asset, we just have to provide it as a second argument. The argument passed in first will be the handed through to the requestURL(key: string, baseURL: string)
as the baseURL
. So it does not have to actually be a valid url.
new StaticAsset("my-avatar-1", new MyCustomResourceProvider(myLoggedInUser));
Keeping assets in the browser storage
For the special case you might want to keep assets in the e.g. local or session storage of the browser, there is also a LocalStorageAsset
.
To convert an existing asset into a LocalStorageAsset
you may do the following:
const myAsset = myAvatar.asset;
const myLocalStorageAsset = await LocalStorageAsset.createFromAsset(myAsset, "my-avatar-asset-1", window.sessionStorage);
const restoredAvatar = await virtualDressingRoom.createAvatar(myLocalStorageAsset);
In this example we take the asset of a generated avatar and create a new asset in the sessionStorage
of our browser. Then we recreate the avatar from this new asset.
Creating an LocalStorageAsset
does only make sense when the asset you create it from is created on the fly (via a compute server call maybe) and therefore stored in memory. Storing whole large StaticAsset
s may take up a lot of browser storage.
A good use case for using a LocalStorageAsset
is for storing generated personalised mannequins.
If you have stored a LocalStorageAsset
in a previous browser session in the e.g. local storage you can then just use the default constructor to create the asset object to handle it.
const myLocalStorageAsset = new LocalStorageAsset("my-avatar-asset-1", window.localStorage)
In cases where it might happen that the user clears his browser storage, you should check if the stored asset is valid: myLocalStorageAsset.isValid()
You can also cleanup a stored asset by calling: myLocalStorageAsset.cleanup()
. This will release any occupied space by the asset.