Skip to content

Commit 385e829

Browse files
author
Ray Schamp
committed
feat: replace cache with createAsset. Deprecate cache
Discourage use of Storage.cache, and provide asset factory storage.createAsset. Towards scratchfoundation/scratch-vm#1577
1 parent 65883da commit 385e829

File tree

3 files changed

+45
-11
lines changed

3 files changed

+45
-11
lines changed

src/Asset.js

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ if (typeof TextDecoder === 'undefined' || typeof TextEncoder === 'undefined') {
1313
}
1414

1515
const base64js = require('base64-js');
16+
const md5 = require('js-md5');
1617

1718
const memoizedToString = (function () {
1819
const strings = {};
@@ -31,21 +32,22 @@ class Asset {
3132
* @param {string} assetId - The ID of this asset.
3233
* @param {DataFormat} [dataFormat] - The format of the data (WAV, PNG, etc.); required iff `data` is present.
3334
* @param {Buffer} [data] - The in-memory data for this asset; optional.
35+
* @param {bool} [generateId] - Whether to create id from an md5 hash of data
3436
*/
35-
constructor (assetType, assetId, dataFormat, data) {
37+
constructor (assetType, assetId, dataFormat, data, generateId) {
3638
/** @type {AssetType} */
3739
this.assetType = assetType;
3840

3941
/** @type {string} */
4042
this.assetId = assetId;
4143

42-
this.setData(data, dataFormat || assetType.runtimeFormat);
44+
this.setData(data, dataFormat || assetType.runtimeFormat, generateId);
4345

4446
/** @type {Asset[]} */
4547
this.dependencies = [];
4648
}
4749

48-
setData (data, dataFormat) {
50+
setData (data, dataFormat, generateId) {
4951
if (data && !dataFormat) {
5052
throw new Error('Data provided without specifying its format');
5153
}
@@ -55,6 +57,8 @@ class Asset {
5557

5658
/** @type {Buffer} */
5759
this.data = data;
60+
61+
if (generateId) this.assetId = md5(data);
5862
}
5963

6064
/**
@@ -69,10 +73,11 @@ class Asset {
6973
* Same as `setData` but encodes text first.
7074
* @param {string} data - the text data to encode and store.
7175
* @param {DataFormat} dataFormat - the format of the data (DataFormat.SVG for example).
76+
* @param {bool} generateId - after setting data, set the id to an md5 of the data?
7277
*/
73-
encodeTextData (data, dataFormat) {
78+
encodeTextData (data, dataFormat, generateId) {
7479
const encoder = new _TextEncoder();
75-
this.setData(encoder.encode(data), dataFormat);
80+
this.setData(encoder.encode(data), dataFormat, generateId);
7681
}
7782

7883
/**

src/BuiltinHelper.js

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ class BuiltinHelper extends Helper {
6363
this.assets = {};
6464

6565
BuiltinAssets.forEach(assetRecord => {
66-
assetRecord.id = this.store(assetRecord.type, assetRecord.format, assetRecord.data, assetRecord.id);
66+
assetRecord.id = this._store(assetRecord.type, assetRecord.format, assetRecord.data, assetRecord.id);
6767
});
6868
}
6969

@@ -109,14 +109,28 @@ class BuiltinHelper extends Helper {
109109
}
110110

111111
/**
112-
* Cache an asset for future lookups by ID.
112+
* Deprecated external API for _store
113+
* @deprecated Not for external use. Create assets and keep track of them outside of the storage instance.
113114
* @param {AssetType} assetType - The type of the asset to cache.
114115
* @param {DataFormat} dataFormat - The dataFormat of the data for the cached asset.
115116
* @param {Buffer} data - The data for the cached asset.
116117
* @param {(string|number)} id - The id for the cached asset.
117118
* @returns {string} The calculated id of the cached asset, or the supplied id if the asset is mutable.
118119
*/
119120
store (assetType, dataFormat, data, id) {
121+
log.warn('Deprecation: use Storage.createAsset. BuiltinHelper is for internal use only.');
122+
return this._store(assetType, dataFormat, data, id);
123+
}
124+
125+
/**
126+
* Cache an asset for future lookups by ID.
127+
* @param {AssetType} assetType - The type of the asset to cache.
128+
* @param {DataFormat} dataFormat - The dataFormat of the data for the cached asset.
129+
* @param {Buffer} data - The data for the cached asset.
130+
* @param {(string|number)} id - The id for the cached asset.
131+
* @returns {string} The calculated id of the cached asset, or the supplied id if the asset is mutable.
132+
*/
133+
_store (assetType, dataFormat, data, id) {
120134
if (!dataFormat) throw new Error('Data cached without specifying its format');
121135
if (id !== '' && id !== null && typeof id !== 'undefined') {
122136
if (this.assets.hasOwnProperty(id) && assetType.immutable) return id;

src/ScratchStorage.js

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -68,15 +68,30 @@ class ScratchStorage {
6868
}
6969

7070
/**
71-
* Cache an asset for future lookups by ID.
71+
* Deprecated API for caching built-in assets. Use createAsset.
7272
* @param {AssetType} assetType - The type of the asset to cache.
7373
* @param {DataFormat} dataFormat - The dataFormat of the data for the cached asset.
7474
* @param {Buffer} data - The data for the cached asset.
7575
* @param {string} id - The id for the cached asset.
7676
* @returns {string} The calculated id of the cached asset, or the supplied id if the asset is mutable.
7777
*/
7878
cache (assetType, dataFormat, data, id) {
79-
return this.builtinHelper.store(assetType, dataFormat, data, id);
79+
log.warn('Deprecation: Storage.cache is deprecated. Use Storage.createAsset, and store assets externally.');
80+
return this.builtinHelper._store(assetType, dataFormat, data, id);
81+
}
82+
83+
/**
84+
* Construct an Asset, and optionally generate an md5 hash of its data to create an id
85+
* @param {AssetType} assetType - The type of the asset to cache.
86+
* @param {DataFormat} dataFormat - The dataFormat of the data for the cached asset.
87+
* @param {Buffer} data - The data for the cached asset.
88+
* @param {string} [id] - The id for the cached asset.
89+
* @param {bool} [generateId] - flag to set id to an md5 hash of data if `id` isn't supplied
90+
* @returns {Asset} generated Asset with `id` attribute set if not supplied
91+
*/
92+
createAsset (assetType, dataFormat, data, id, generateId) {
93+
if (!dataFormat) throw new Error('Tried to create asset without a dataFormat');
94+
return new _Asset(assetType, id, dataFormat, data, generateId);
8095
}
8196

8297
/**
@@ -154,7 +169,7 @@ class ScratchStorage {
154169
} else {
155170
// TODO? this.localHelper.cache(assetType, assetId, asset);
156171
if (helper !== this.builtinHelper && assetType.immutable) {
157-
asset.assetId = this.builtinHelper.cache(
172+
asset.assetId = this.builtinHelper._store(
158173
assetType,
159174
asset.dataFormat,
160175
asset.data,
@@ -198,7 +213,7 @@ class ScratchStorage {
198213
(resolve, reject) =>
199214
this.webHelper.store(assetType, dataFormat, data, assetId)
200215
.then(body => {
201-
this.builtinHelper.store(assetType, dataFormat, data, body.id);
216+
this.builtinHelper._store(assetType, dataFormat, data, body.id);
202217
return resolve(body);
203218
})
204219
.catch(error => reject(error))

0 commit comments

Comments
 (0)