@anvilkit/plugin-asset-manager 0.1.2 → 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +366 -108
- package/dist/adapters/data-url.cjs +6 -2
- package/dist/adapters/data-url.d.cts.map +1 -1
- package/dist/adapters/data-url.d.ts.map +1 -1
- package/dist/adapters/data-url.js +6 -2
- package/dist/adapters/extract-image-dimensions.cjs +9 -0
- package/dist/adapters/extract-image-dimensions.d.cts +6 -0
- package/dist/adapters/extract-image-dimensions.d.cts.map +1 -1
- package/dist/adapters/extract-image-dimensions.d.ts +6 -0
- package/dist/adapters/extract-image-dimensions.d.ts.map +1 -1
- package/dist/adapters/extract-image-dimensions.js +9 -0
- package/dist/adapters/in-memory.cjs +6 -4
- package/dist/adapters/in-memory.d.cts +6 -0
- package/dist/adapters/in-memory.d.cts.map +1 -1
- package/dist/adapters/in-memory.d.ts +6 -0
- package/dist/adapters/in-memory.d.ts.map +1 -1
- package/dist/adapters/in-memory.js +6 -4
- package/dist/adapters/s3-presigned.cjs +78 -28
- package/dist/adapters/s3-presigned.d.cts +1 -0
- package/dist/adapters/s3-presigned.d.cts.map +1 -1
- package/dist/adapters/s3-presigned.d.ts +1 -0
- package/dist/adapters/s3-presigned.d.ts.map +1 -1
- package/dist/adapters/s3-presigned.js +78 -28
- package/dist/csp.d.cts.map +1 -1
- package/dist/csp.d.ts.map +1 -1
- package/dist/errors.d.cts.map +1 -1
- package/dist/errors.d.ts.map +1 -1
- package/dist/index.d.cts +3 -3
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/plugin.cjs +32 -5
- package/dist/plugin.d.cts +4 -3
- package/dist/plugin.d.cts.map +1 -1
- package/dist/plugin.d.ts +4 -3
- package/dist/plugin.d.ts.map +1 -1
- package/dist/plugin.js +22 -5
- package/dist/registry.d.cts.map +1 -1
- package/dist/registry.d.ts.map +1 -1
- package/dist/resolver.cjs +6 -1
- package/dist/resolver.d.cts.map +1 -1
- package/dist/resolver.d.ts.map +1 -1
- package/dist/resolver.js +6 -1
- package/dist/retry.cjs +10 -8
- package/dist/retry.d.cts.map +1 -1
- package/dist/retry.d.ts.map +1 -1
- package/dist/retry.js +10 -8
- package/dist/studio-asset-source.cjs +26 -5
- package/dist/studio-asset-source.d.cts +2 -2
- package/dist/studio-asset-source.d.cts.map +1 -1
- package/dist/studio-asset-source.d.ts +2 -2
- package/dist/studio-asset-source.d.ts.map +1 -1
- package/dist/studio-asset-source.js +26 -5
- package/dist/testing/index.d.cts.map +1 -1
- package/dist/testing/index.d.ts.map +1 -1
- package/dist/types.d.cts +9 -1
- package/dist/types.d.cts.map +1 -1
- package/dist/types.d.ts +9 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/ui/AssetBrowser.cjs +54 -19
- package/dist/ui/AssetBrowser.d.cts +10 -1
- package/dist/ui/AssetBrowser.d.cts.map +1 -1
- package/dist/ui/AssetBrowser.d.ts +10 -1
- package/dist/ui/AssetBrowser.d.ts.map +1 -1
- package/dist/ui/AssetBrowser.js +54 -19
- package/dist/ui/AssetCommandPalette.cjs +18 -9
- package/dist/ui/AssetCommandPalette.d.cts.map +1 -1
- package/dist/ui/AssetCommandPalette.d.ts.map +1 -1
- package/dist/ui/AssetCommandPalette.js +18 -9
- package/dist/ui/AssetManagerUI.cjs +1 -0
- package/dist/ui/AssetManagerUI.d.cts.map +1 -1
- package/dist/ui/AssetManagerUI.d.ts.map +1 -1
- package/dist/ui/AssetManagerUI.js +1 -0
- package/dist/ui/DeleteAssetDialog.cjs +1 -0
- package/dist/ui/DeleteAssetDialog.d.cts.map +1 -1
- package/dist/ui/DeleteAssetDialog.d.ts.map +1 -1
- package/dist/ui/DeleteAssetDialog.js +1 -0
- package/dist/ui/MetadataPanel.cjs +1 -0
- package/dist/ui/MetadataPanel.d.cts.map +1 -1
- package/dist/ui/MetadataPanel.d.ts.map +1 -1
- package/dist/ui/MetadataPanel.js +1 -0
- package/dist/ui/ReplaceAssetDialog.cjs +1 -0
- package/dist/ui/ReplaceAssetDialog.d.cts.map +1 -1
- package/dist/ui/ReplaceAssetDialog.d.ts.map +1 -1
- package/dist/ui/ReplaceAssetDialog.js +1 -0
- package/dist/ui/UploadButton.cjs +22 -7
- package/dist/ui/UploadButton.d.cts.map +1 -1
- package/dist/ui/UploadButton.d.ts.map +1 -1
- package/dist/ui/UploadButton.js +22 -7
- package/dist/ui/index.d.cts.map +1 -1
- package/dist/ui/index.d.ts.map +1 -1
- package/dist/validate-upload-result.cjs +49 -10
- package/dist/validate-upload-result.d.cts.map +1 -1
- package/dist/validate-upload-result.d.ts.map +1 -1
- package/dist/validate-upload-result.js +49 -10
- package/package.json +5 -5
package/dist/plugin.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,YAAY,EACZ,mBAAmB,EAEpB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,KAAK,EAAE,MAAM,IAAI,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAG7D,OAAO,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAO5D,OAAO,KAAK,EACV,mBAAmB,EAEnB,aAAa,EACb,YAAY,EACb,MAAM,YAAY,CAAC;AAGpB,OAAO,EAAE,oBAAoB,EAAE,CAAC;AA4BhC,wBAAgB,wBAAwB,CACtC,UAAU,SAAS,UAAU,GAAG,UAAU,EAC1C,OAAO,EAAE,mBAAmB,GAAG,YAAY,CAAC,UAAU,CAAC,CAwDxD;AAED,wBAAgB,gBAAgB,CAAC,UAAU,SAAS,UAAU,GAAG,UAAU,EACzE,GAAG,EAAE,mBAAmB,CAAC,UAAU,CAAC,GACnC,aAAa,GAAG,SAAS,CAG3B;AAED,wBAAsB,WAAW,CAAC,UAAU,SAAS,UAAU,GAAG,UAAU,EAC1E,GAAG,EAAE,mBAAmB,CAAC,UAAU,CAAC,EACpC,IAAI,EAAE,IAAI,EACV,MAAM,CAAC,EAAE,WAAW,GACnB,OAAO,CAAC,YAAY,CAAC,CAwDvB;AAED,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,IAAI,EACV,OAAO,EAAE,IAAI,CAAC,mBAAmB,EAAE,mBAAmB,GAAG,aAAa,CAAC,GACtE,IAAI,CAmBN"}
|
package/dist/plugin.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import package_0 from "../package.json";
|
|
1
2
|
import { createAssetReference } from "./asset-reference.js";
|
|
2
3
|
import { AssetValidationError } from "./errors.js";
|
|
3
4
|
import { uploadAssetAction } from "./header-action.js";
|
|
@@ -9,7 +10,7 @@ import { validateUploadResult } from "./validate-upload-result.js";
|
|
|
9
10
|
const META = {
|
|
10
11
|
id: "anvilkit-plugin-asset-manager",
|
|
11
12
|
name: "Asset Manager",
|
|
12
|
-
version:
|
|
13
|
+
version: package_0.version,
|
|
13
14
|
coreVersion: "^0.1.0-alpha",
|
|
14
15
|
description: "Headless asset upload plugin with host-provided persistence and a separate React UI subpath."
|
|
15
16
|
};
|
|
@@ -44,7 +45,7 @@ function createAssetManagerPlugin(options) {
|
|
|
44
45
|
initCtx.registerAssetResolver(assetResolver);
|
|
45
46
|
const studioAssetSource = createStudioAssetSource({
|
|
46
47
|
registry,
|
|
47
|
-
upload: (file)=>uploadAsset(initCtx, file),
|
|
48
|
+
upload: (file, opts)=>uploadAsset(initCtx, file, opts?.signal),
|
|
48
49
|
...normalizedOptions.getThumbnail ? {
|
|
49
50
|
getThumbnail: normalizedOptions.getThumbnail
|
|
50
51
|
} : {}
|
|
@@ -68,12 +69,15 @@ function getAssetRegistry(ctx) {
|
|
|
68
69
|
const token = tokenByContext.get(ctx);
|
|
69
70
|
return token ? stateByToken.get(token)?.registry : void 0;
|
|
70
71
|
}
|
|
71
|
-
async function uploadAsset(ctx, file) {
|
|
72
|
+
async function uploadAsset(ctx, file, signal) {
|
|
72
73
|
const state = getRuntimeState(ctx);
|
|
73
74
|
const { options, registry } = state;
|
|
74
75
|
try {
|
|
75
76
|
validateSelectedFile(file, options);
|
|
76
|
-
const uploadResult = await options.uploader(file
|
|
77
|
+
const uploadResult = await options.uploader(file, signal ? {
|
|
78
|
+
signal
|
|
79
|
+
} : void 0);
|
|
80
|
+
if (signal?.aborted) throw makePluginAbortError();
|
|
77
81
|
const validated = validateUploadResult(mergeUploadMeta(uploadResult, file), options);
|
|
78
82
|
const tagged = withDerivedTags(validated, file);
|
|
79
83
|
const stored = registry.register(tagged);
|
|
@@ -84,6 +88,7 @@ async function uploadAsset(ctx, file) {
|
|
|
84
88
|
});
|
|
85
89
|
return stored;
|
|
86
90
|
} catch (error) {
|
|
91
|
+
if (isAbortLikeError(error) || signal?.aborted) throw error;
|
|
87
92
|
const normalizedError = error instanceof AssetValidationError ? error : new AssetValidationError("UPLOAD_FAILED", error instanceof Error ? error.message : String(error), {
|
|
88
93
|
cause: error
|
|
89
94
|
});
|
|
@@ -170,7 +175,8 @@ function mimeTypeMatches(input, acceptedMimeTypes) {
|
|
|
170
175
|
}
|
|
171
176
|
function dispatchAssetReference(ctx, asset) {
|
|
172
177
|
const currentData = ctx.getData();
|
|
173
|
-
const
|
|
178
|
+
const assetsView = currentData.assets;
|
|
179
|
+
const currentAssetsRaw = Array.isArray(assetsView) ? assetsView : [];
|
|
174
180
|
const assetEntry = toIRAsset(asset);
|
|
175
181
|
const nextAssets = [];
|
|
176
182
|
let replaced = false;
|
|
@@ -209,4 +215,15 @@ function inferIRAssetKind(mimeType, url) {
|
|
|
209
215
|
function isRecord(value) {
|
|
210
216
|
return "object" == typeof value && null !== value;
|
|
211
217
|
}
|
|
218
|
+
function makePluginAbortError() {
|
|
219
|
+
if ("u" > typeof DOMException) return new DOMException("Upload aborted", "AbortError");
|
|
220
|
+
const error = new Error("Upload aborted");
|
|
221
|
+
error.name = "AbortError";
|
|
222
|
+
return error;
|
|
223
|
+
}
|
|
224
|
+
function isAbortLikeError(error) {
|
|
225
|
+
if (null === error || "object" != typeof error) return false;
|
|
226
|
+
const name = error.name;
|
|
227
|
+
return "AbortError" === name;
|
|
228
|
+
}
|
|
212
229
|
export { createAssetManagerPlugin, createAssetReference, getAssetRegistry, uploadAsset, validateSelectedFile };
|
package/dist/registry.d.cts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"registry.d.cts","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"registry.d.cts","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,aAAa,EAKd,MAAM,YAAY,CAAC;AAIpB,wBAAgB,mBAAmB,IAAI,aAAa,CA6EnD"}
|
package/dist/registry.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,aAAa,EAKd,MAAM,YAAY,CAAC;AAIpB,wBAAgB,mBAAmB,IAAI,aAAa,CA6EnD"}
|
package/dist/resolver.cjs
CHANGED
|
@@ -137,7 +137,7 @@ function cloneNode(node, rewriteMap) {
|
|
|
137
137
|
return {
|
|
138
138
|
id: node.id,
|
|
139
139
|
type: node.type,
|
|
140
|
-
props:
|
|
140
|
+
props: cloneProps(node.props, rewriteMap),
|
|
141
141
|
...node.children ? {
|
|
142
142
|
children: node.children.map((child)=>cloneNode(child, rewriteMap))
|
|
143
143
|
} : {},
|
|
@@ -157,6 +157,11 @@ function cloneAsset(asset, rewriteMap) {
|
|
|
157
157
|
} : {}
|
|
158
158
|
};
|
|
159
159
|
}
|
|
160
|
+
function cloneProps(props, rewriteMap) {
|
|
161
|
+
const next = {};
|
|
162
|
+
for (const [key, value] of Object.entries(props))next[key] = cloneValue(value, rewriteMap, key);
|
|
163
|
+
return next;
|
|
164
|
+
}
|
|
160
165
|
function cloneValue(value, rewriteMap, key) {
|
|
161
166
|
if (Array.isArray(value)) return value.map((item)=>cloneValue(item, rewriteMap));
|
|
162
167
|
if ("string" == typeof value) {
|
package/dist/resolver.d.cts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resolver.d.cts","sourceRoot":"","sources":["../src/resolver.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"resolver.d.cts","sourceRoot":"","sources":["../src/resolver.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,eAAe,EACf,MAAM,EAGP,MAAM,sBAAsB,CAAC;AAG9B,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AA6BhD,MAAM,WAAW,4BAA4B;IAC3C,QAAQ,CAAC,QAAQ,EAAE,aAAa,CAAC;IACjC,QAAQ,CAAC,qBAAqB,CAAC,EAAE,OAAO,CAAC;IACzC,QAAQ,CAAC,yBAAyB,CAAC,EAAE,OAAO,CAAC;CAC9C;AAED,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,4BAA4B,GACpC,eAAe,CAgDjB;AAED,wBAAsB,aAAa,CACjC,EAAE,EAAE,MAAM,EACV,QAAQ,EAAE,eAAe,GACxB,OAAO,CAAC,MAAM,CAAC,CAmBjB"}
|
package/dist/resolver.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resolver.d.ts","sourceRoot":"","sources":["../src/resolver.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"resolver.d.ts","sourceRoot":"","sources":["../src/resolver.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,eAAe,EACf,MAAM,EAGP,MAAM,sBAAsB,CAAC;AAG9B,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AA6BhD,MAAM,WAAW,4BAA4B;IAC3C,QAAQ,CAAC,QAAQ,EAAE,aAAa,CAAC;IACjC,QAAQ,CAAC,qBAAqB,CAAC,EAAE,OAAO,CAAC;IACzC,QAAQ,CAAC,yBAAyB,CAAC,EAAE,OAAO,CAAC;CAC9C;AAED,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,4BAA4B,GACpC,eAAe,CAgDjB;AAED,wBAAsB,aAAa,CACjC,EAAE,EAAE,MAAM,EACV,QAAQ,EAAE,eAAe,GACxB,OAAO,CAAC,MAAM,CAAC,CAmBjB"}
|
package/dist/resolver.js
CHANGED
|
@@ -108,7 +108,7 @@ function cloneNode(node, rewriteMap) {
|
|
|
108
108
|
return {
|
|
109
109
|
id: node.id,
|
|
110
110
|
type: node.type,
|
|
111
|
-
props:
|
|
111
|
+
props: cloneProps(node.props, rewriteMap),
|
|
112
112
|
...node.children ? {
|
|
113
113
|
children: node.children.map((child)=>cloneNode(child, rewriteMap))
|
|
114
114
|
} : {},
|
|
@@ -128,6 +128,11 @@ function cloneAsset(asset, rewriteMap) {
|
|
|
128
128
|
} : {}
|
|
129
129
|
};
|
|
130
130
|
}
|
|
131
|
+
function cloneProps(props, rewriteMap) {
|
|
132
|
+
const next = {};
|
|
133
|
+
for (const [key, value] of Object.entries(props))next[key] = cloneValue(value, rewriteMap, key);
|
|
134
|
+
return next;
|
|
135
|
+
}
|
|
131
136
|
function cloneValue(value, rewriteMap, key) {
|
|
132
137
|
if (Array.isArray(value)) return value.map((item)=>cloneValue(item, rewriteMap));
|
|
133
138
|
if ("string" == typeof value) {
|
package/dist/retry.cjs
CHANGED
|
@@ -92,21 +92,23 @@ function defaultSleep(ms, signal) {
|
|
|
92
92
|
return Promise.resolve();
|
|
93
93
|
}
|
|
94
94
|
return new Promise((resolve, reject)=>{
|
|
95
|
+
let onAbort;
|
|
95
96
|
const timer = setTimeout(()=>{
|
|
96
|
-
signal
|
|
97
|
+
if (signal && onAbort) signal.removeEventListener("abort", onAbort);
|
|
97
98
|
resolve();
|
|
98
99
|
}, ms);
|
|
99
|
-
const onAbort = ()=>{
|
|
100
|
-
clearTimeout(timer);
|
|
101
|
-
reject(makeAbortError(signal));
|
|
102
|
-
};
|
|
103
100
|
if (signal) {
|
|
104
|
-
|
|
101
|
+
const activeSignal = signal;
|
|
102
|
+
onAbort = ()=>{
|
|
105
103
|
clearTimeout(timer);
|
|
106
|
-
reject(makeAbortError(
|
|
104
|
+
reject(makeAbortError(activeSignal));
|
|
105
|
+
};
|
|
106
|
+
if (activeSignal.aborted) {
|
|
107
|
+
clearTimeout(timer);
|
|
108
|
+
reject(makeAbortError(activeSignal));
|
|
107
109
|
return;
|
|
108
110
|
}
|
|
109
|
-
|
|
111
|
+
activeSignal.addEventListener("abort", onAbort, {
|
|
110
112
|
once: true
|
|
111
113
|
});
|
|
112
114
|
}
|
package/dist/retry.d.cts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"retry.d.cts","sourceRoot":"","sources":["../src/retry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH;;;;;;;;;;;GAWG;AACH,qBAAa,cAAe,SAAQ,KAAK;
|
|
1
|
+
{"version":3,"file":"retry.d.cts","sourceRoot":"","sources":["../src/retry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH;;;;;;;;;;;GAWG;AACH,qBAAa,cAAe,SAAQ,KAAK;IACvC,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;gBAG7B,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE;QAAE,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC;QAAC,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAA;KAAE;CAYzE;AAED,MAAM,WAAW,YAAY;IAC3B;;;;;OAKG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B;;;;;OAKG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B;;;;OAIG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,kEAAkE;IAClE,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAC;IAC9B,mEAAmE;IACnE,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,MAAM,CAAC;IAC/B,2DAA2D;IAC3D,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACtE;AAMD;;;;;;;;;GASG;AACH,wBAAsB,SAAS,CAAC,CAAC,EAC/B,EAAE,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,CAAC,CAAC,EACnC,OAAO,GAAE,YAAiB,GACzB,OAAO,CAAC,CAAC,CAAC,CAmCZ"}
|
package/dist/retry.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"retry.d.ts","sourceRoot":"","sources":["../src/retry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH;;;;;;;;;;;GAWG;AACH,qBAAa,cAAe,SAAQ,KAAK;
|
|
1
|
+
{"version":3,"file":"retry.d.ts","sourceRoot":"","sources":["../src/retry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH;;;;;;;;;;;GAWG;AACH,qBAAa,cAAe,SAAQ,KAAK;IACvC,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;gBAG7B,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE;QAAE,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC;QAAC,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAA;KAAE;CAYzE;AAED,MAAM,WAAW,YAAY;IAC3B;;;;;OAKG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B;;;;;OAKG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B;;;;OAIG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,kEAAkE;IAClE,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAC;IAC9B,mEAAmE;IACnE,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,MAAM,CAAC;IAC/B,2DAA2D;IAC3D,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACtE;AAMD;;;;;;;;;GASG;AACH,wBAAsB,SAAS,CAAC,CAAC,EAC/B,EAAE,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,CAAC,CAAC,EACnC,OAAO,GAAE,YAAiB,GACzB,OAAO,CAAC,CAAC,CAAC,CAmCZ"}
|
package/dist/retry.js
CHANGED
|
@@ -63,21 +63,23 @@ function defaultSleep(ms, signal) {
|
|
|
63
63
|
return Promise.resolve();
|
|
64
64
|
}
|
|
65
65
|
return new Promise((resolve, reject)=>{
|
|
66
|
+
let onAbort;
|
|
66
67
|
const timer = setTimeout(()=>{
|
|
67
|
-
signal
|
|
68
|
+
if (signal && onAbort) signal.removeEventListener("abort", onAbort);
|
|
68
69
|
resolve();
|
|
69
70
|
}, ms);
|
|
70
|
-
const onAbort = ()=>{
|
|
71
|
-
clearTimeout(timer);
|
|
72
|
-
reject(makeAbortError(signal));
|
|
73
|
-
};
|
|
74
71
|
if (signal) {
|
|
75
|
-
|
|
72
|
+
const activeSignal = signal;
|
|
73
|
+
onAbort = ()=>{
|
|
76
74
|
clearTimeout(timer);
|
|
77
|
-
reject(makeAbortError(
|
|
75
|
+
reject(makeAbortError(activeSignal));
|
|
76
|
+
};
|
|
77
|
+
if (activeSignal.aborted) {
|
|
78
|
+
clearTimeout(timer);
|
|
79
|
+
reject(makeAbortError(activeSignal));
|
|
78
80
|
return;
|
|
79
81
|
}
|
|
80
|
-
|
|
82
|
+
activeSignal.addEventListener("abort", onAbort, {
|
|
81
83
|
once: true
|
|
82
84
|
});
|
|
83
85
|
}
|
|
@@ -68,7 +68,7 @@ function createStudioAssetSource(options) {
|
|
|
68
68
|
};
|
|
69
69
|
return Promise.resolve(projected);
|
|
70
70
|
},
|
|
71
|
-
async upload (files, listener) {
|
|
71
|
+
async upload (files, listener, signal) {
|
|
72
72
|
const fileList = Array.from(files);
|
|
73
73
|
if (0 === fileList.length) return [];
|
|
74
74
|
const totalBytes = fileList.reduce((acc, file)=>acc + file.size, 0);
|
|
@@ -80,6 +80,13 @@ function createStudioAssetSource(options) {
|
|
|
80
80
|
listener?.(event);
|
|
81
81
|
fanOut(event);
|
|
82
82
|
};
|
|
83
|
+
const abortFromSignal = ()=>{
|
|
84
|
+
if (void 0 === abortError) abortError = signal?.reason instanceof Error ? signal.reason : makeAbortError();
|
|
85
|
+
};
|
|
86
|
+
if (signal?.aborted) abortFromSignal();
|
|
87
|
+
signal?.addEventListener("abort", abortFromSignal, {
|
|
88
|
+
once: true
|
|
89
|
+
});
|
|
83
90
|
const runWorker = async ()=>{
|
|
84
91
|
while(true){
|
|
85
92
|
if (void 0 !== abortError) return;
|
|
@@ -88,7 +95,10 @@ function createStudioAssetSource(options) {
|
|
|
88
95
|
const file = fileList[index];
|
|
89
96
|
if (void 0 === file) return;
|
|
90
97
|
try {
|
|
91
|
-
const result = await upload(file
|
|
98
|
+
const result = await upload(file, {
|
|
99
|
+
signal
|
|
100
|
+
});
|
|
101
|
+
if (void 0 !== abortError) return;
|
|
92
102
|
bytesUploaded += file.size;
|
|
93
103
|
const asset = project(result);
|
|
94
104
|
results[index] = asset;
|
|
@@ -106,6 +116,7 @@ function createStudioAssetSource(options) {
|
|
|
106
116
|
abortError = error;
|
|
107
117
|
return;
|
|
108
118
|
}
|
|
119
|
+
if (void 0 !== abortError || signal?.aborted) return;
|
|
109
120
|
const message = error instanceof Error ? error.message : String(error);
|
|
110
121
|
emit({
|
|
111
122
|
type: "error",
|
|
@@ -117,9 +128,13 @@ function createStudioAssetSource(options) {
|
|
|
117
128
|
const workerCount = Math.min(maxConcurrent, fileList.length);
|
|
118
129
|
const workers = [];
|
|
119
130
|
for(let i = 0; i < workerCount; i += 1)workers.push(runWorker());
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
131
|
+
try {
|
|
132
|
+
await Promise.all(workers);
|
|
133
|
+
if (void 0 !== abortError) throw abortError;
|
|
134
|
+
return results.filter((value)=>null !== value);
|
|
135
|
+
} finally{
|
|
136
|
+
signal?.removeEventListener("abort", abortFromSignal);
|
|
137
|
+
}
|
|
123
138
|
},
|
|
124
139
|
delete (assetId) {
|
|
125
140
|
registry.delete(assetId);
|
|
@@ -198,6 +213,12 @@ function isAbortError(error) {
|
|
|
198
213
|
const name = error.name;
|
|
199
214
|
return "AbortError" === name;
|
|
200
215
|
}
|
|
216
|
+
function makeAbortError() {
|
|
217
|
+
if ("u" > typeof DOMException) return new DOMException("Upload aborted", "AbortError");
|
|
218
|
+
const error = new Error("Upload aborted");
|
|
219
|
+
error.name = "AbortError";
|
|
220
|
+
return error;
|
|
221
|
+
}
|
|
201
222
|
exports.MAX_CONCURRENT_UPLOADS = __webpack_exports__.MAX_CONCURRENT_UPLOADS;
|
|
202
223
|
exports.createStudioAssetSource = __webpack_exports__.createStudioAssetSource;
|
|
203
224
|
exports.inferStudioAssetKind = __webpack_exports__.inferStudioAssetKind;
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
* registry so the IR resolver and the sidebar see the same data.
|
|
13
13
|
*/
|
|
14
14
|
import type { StudioAssetKind, StudioAssetSource } from "@anvilkit/core/types";
|
|
15
|
-
import type { AssetRegistry, UploadResult } from "./types.js";
|
|
15
|
+
import type { AssetRegistry, UploadAdapterOptions, UploadResult } from "./types.js";
|
|
16
16
|
/**
|
|
17
17
|
* Default concurrency cap for batched uploads. Editors typically drag
|
|
18
18
|
* 1–10 files at a time; three concurrent uploads strikes a balance
|
|
@@ -25,7 +25,7 @@ export interface CreateStudioAssetSourceOptions {
|
|
|
25
25
|
* Performs the upload. Provided by the plugin so the adapter does
|
|
26
26
|
* not need to depend on `StudioPluginContext` directly.
|
|
27
27
|
*/
|
|
28
|
-
readonly upload: (file: File) => Promise<UploadResult>;
|
|
28
|
+
readonly upload: (file: File, options?: UploadAdapterOptions) => Promise<UploadResult>;
|
|
29
29
|
/**
|
|
30
30
|
* Optional thumbnail derivation. Returning a string sets
|
|
31
31
|
* `StudioAsset.thumbnailUrl`; returning `undefined` suppresses the
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"studio-asset-source.d.cts","sourceRoot":"","sources":["../src/studio-asset-source.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"studio-asset-source.d.cts","sourceRoot":"","sources":["../src/studio-asset-source.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAEV,eAAe,EAGf,iBAAiB,EAGlB,MAAM,sBAAsB,CAAC;AAI9B,OAAO,KAAK,EACV,aAAa,EACb,oBAAoB,EACpB,YAAY,EACb,MAAM,YAAY,CAAC;AAEpB;;;;GAIG;AACH,eAAO,MAAM,sBAAsB,IAAI,CAAC;AAExC,MAAM,WAAW,8BAA8B;IAC7C,QAAQ,CAAC,QAAQ,EAAE,aAAa,CAAC;IACjC;;;OAGG;IACH,QAAQ,CAAC,MAAM,EAAE,CACf,IAAI,EAAE,IAAI,EACV,OAAO,CAAC,EAAE,oBAAoB,KAC3B,OAAO,CAAC,YAAY,CAAC,CAAC;IAC3B;;;;;;;OAOG;IACH,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC,KAAK,EAAE,YAAY,KAAK,MAAM,GAAG,SAAS,CAAC;IACpE;;;;OAIG;IACH,QAAQ,CAAC,oBAAoB,CAAC,EAAE,MAAM,CAAC;CACxC;AAED,wBAAgB,uBAAuB,CACrC,OAAO,EAAE,8BAA8B,GACtC,iBAAiB,CAqLnB;AA4BD;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,YAAY,GAAG,eAAe,CAEzE"}
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
* registry so the IR resolver and the sidebar see the same data.
|
|
13
13
|
*/
|
|
14
14
|
import type { StudioAssetKind, StudioAssetSource } from "@anvilkit/core/types";
|
|
15
|
-
import type { AssetRegistry, UploadResult } from "./types.js";
|
|
15
|
+
import type { AssetRegistry, UploadAdapterOptions, UploadResult } from "./types.js";
|
|
16
16
|
/**
|
|
17
17
|
* Default concurrency cap for batched uploads. Editors typically drag
|
|
18
18
|
* 1–10 files at a time; three concurrent uploads strikes a balance
|
|
@@ -25,7 +25,7 @@ export interface CreateStudioAssetSourceOptions {
|
|
|
25
25
|
* Performs the upload. Provided by the plugin so the adapter does
|
|
26
26
|
* not need to depend on `StudioPluginContext` directly.
|
|
27
27
|
*/
|
|
28
|
-
readonly upload: (file: File) => Promise<UploadResult>;
|
|
28
|
+
readonly upload: (file: File, options?: UploadAdapterOptions) => Promise<UploadResult>;
|
|
29
29
|
/**
|
|
30
30
|
* Optional thumbnail derivation. Returning a string sets
|
|
31
31
|
* `StudioAsset.thumbnailUrl`; returning `undefined` suppresses the
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"studio-asset-source.d.ts","sourceRoot":"","sources":["../src/studio-asset-source.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"studio-asset-source.d.ts","sourceRoot":"","sources":["../src/studio-asset-source.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAEV,eAAe,EAGf,iBAAiB,EAGlB,MAAM,sBAAsB,CAAC;AAI9B,OAAO,KAAK,EACV,aAAa,EACb,oBAAoB,EACpB,YAAY,EACb,MAAM,YAAY,CAAC;AAEpB;;;;GAIG;AACH,eAAO,MAAM,sBAAsB,IAAI,CAAC;AAExC,MAAM,WAAW,8BAA8B;IAC7C,QAAQ,CAAC,QAAQ,EAAE,aAAa,CAAC;IACjC;;;OAGG;IACH,QAAQ,CAAC,MAAM,EAAE,CACf,IAAI,EAAE,IAAI,EACV,OAAO,CAAC,EAAE,oBAAoB,KAC3B,OAAO,CAAC,YAAY,CAAC,CAAC;IAC3B;;;;;;;OAOG;IACH,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC,KAAK,EAAE,YAAY,KAAK,MAAM,GAAG,SAAS,CAAC;IACpE;;;;OAIG;IACH,QAAQ,CAAC,oBAAoB,CAAC,EAAE,MAAM,CAAC;CACxC;AAED,wBAAgB,uBAAuB,CACrC,OAAO,EAAE,8BAA8B,GACtC,iBAAiB,CAqLnB;AA4BD;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,YAAY,GAAG,eAAe,CAEzE"}
|
|
@@ -38,7 +38,7 @@ function createStudioAssetSource(options) {
|
|
|
38
38
|
};
|
|
39
39
|
return Promise.resolve(projected);
|
|
40
40
|
},
|
|
41
|
-
async upload (files, listener) {
|
|
41
|
+
async upload (files, listener, signal) {
|
|
42
42
|
const fileList = Array.from(files);
|
|
43
43
|
if (0 === fileList.length) return [];
|
|
44
44
|
const totalBytes = fileList.reduce((acc, file)=>acc + file.size, 0);
|
|
@@ -50,6 +50,13 @@ function createStudioAssetSource(options) {
|
|
|
50
50
|
listener?.(event);
|
|
51
51
|
fanOut(event);
|
|
52
52
|
};
|
|
53
|
+
const abortFromSignal = ()=>{
|
|
54
|
+
if (void 0 === abortError) abortError = signal?.reason instanceof Error ? signal.reason : makeAbortError();
|
|
55
|
+
};
|
|
56
|
+
if (signal?.aborted) abortFromSignal();
|
|
57
|
+
signal?.addEventListener("abort", abortFromSignal, {
|
|
58
|
+
once: true
|
|
59
|
+
});
|
|
53
60
|
const runWorker = async ()=>{
|
|
54
61
|
while(true){
|
|
55
62
|
if (void 0 !== abortError) return;
|
|
@@ -58,7 +65,10 @@ function createStudioAssetSource(options) {
|
|
|
58
65
|
const file = fileList[index];
|
|
59
66
|
if (void 0 === file) return;
|
|
60
67
|
try {
|
|
61
|
-
const result = await upload(file
|
|
68
|
+
const result = await upload(file, {
|
|
69
|
+
signal
|
|
70
|
+
});
|
|
71
|
+
if (void 0 !== abortError) return;
|
|
62
72
|
bytesUploaded += file.size;
|
|
63
73
|
const asset = project(result);
|
|
64
74
|
results[index] = asset;
|
|
@@ -76,6 +86,7 @@ function createStudioAssetSource(options) {
|
|
|
76
86
|
abortError = error;
|
|
77
87
|
return;
|
|
78
88
|
}
|
|
89
|
+
if (void 0 !== abortError || signal?.aborted) return;
|
|
79
90
|
const message = error instanceof Error ? error.message : String(error);
|
|
80
91
|
emit({
|
|
81
92
|
type: "error",
|
|
@@ -87,9 +98,13 @@ function createStudioAssetSource(options) {
|
|
|
87
98
|
const workerCount = Math.min(maxConcurrent, fileList.length);
|
|
88
99
|
const workers = [];
|
|
89
100
|
for(let i = 0; i < workerCount; i += 1)workers.push(runWorker());
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
101
|
+
try {
|
|
102
|
+
await Promise.all(workers);
|
|
103
|
+
if (void 0 !== abortError) throw abortError;
|
|
104
|
+
return results.filter((value)=>null !== value);
|
|
105
|
+
} finally{
|
|
106
|
+
signal?.removeEventListener("abort", abortFromSignal);
|
|
107
|
+
}
|
|
93
108
|
},
|
|
94
109
|
delete (assetId) {
|
|
95
110
|
registry.delete(assetId);
|
|
@@ -168,4 +183,10 @@ function isAbortError(error) {
|
|
|
168
183
|
const name = error.name;
|
|
169
184
|
return "AbortError" === name;
|
|
170
185
|
}
|
|
186
|
+
function makeAbortError() {
|
|
187
|
+
if ("u" > typeof DOMException) return new DOMException("Upload aborted", "AbortError");
|
|
188
|
+
const error = new Error("Upload aborted");
|
|
189
|
+
error.name = "AbortError";
|
|
190
|
+
return error;
|
|
191
|
+
}
|
|
171
192
|
export { MAX_CONCURRENT_UPLOADS, createStudioAssetSource, inferStudioAssetKind };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.cts","sourceRoot":"","sources":["../../src/testing/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"index.d.cts","sourceRoot":"","sources":["../../src/testing/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,KAAK,EAEV,aAAa,EACb,aAAa,EACb,YAAY,EACb,MAAM,aAAa,CAAC;AAErB,MAAM,WAAW,yBAAyB;IACxC,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS,YAAY,EAAE,CAAC;CAC5C;AAED,wBAAgB,kBAAkB,CAChC,OAAO,GAAE,yBAA8B,GACtC,aAAa,CAMf;AAED,MAAM,WAAW,mBAAmB;IAClC;;;;;OAKG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;CACnD;AAED,wBAAgB,YAAY,CAAC,OAAO,GAAE,mBAAwB,GAAG,aAAa,CAkB7E"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/testing/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/testing/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,KAAK,EAEV,aAAa,EACb,aAAa,EACb,YAAY,EACb,MAAM,aAAa,CAAC;AAErB,MAAM,WAAW,yBAAyB;IACxC,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS,YAAY,EAAE,CAAC;CAC5C;AAED,wBAAgB,kBAAkB,CAChC,OAAO,GAAE,yBAA8B,GACtC,aAAa,CAMf;AAED,MAAM,WAAW,mBAAmB;IAClC;;;;;OAKG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;CACnD;AAED,wBAAgB,YAAY,CAAC,OAAO,GAAE,mBAAwB,GAAG,aAAa,CAkB7E"}
|
package/dist/types.d.cts
CHANGED
|
@@ -31,7 +31,15 @@ export interface UploadResult {
|
|
|
31
31
|
*/
|
|
32
32
|
readonly tags?: readonly string[];
|
|
33
33
|
}
|
|
34
|
-
|
|
34
|
+
/**
|
|
35
|
+
* Options passed to an {@link UploadAdapter}. Currently carries an
|
|
36
|
+
* optional `AbortSignal` so a cancelled upload batch can short-circuit
|
|
37
|
+
* the adapter (network request, image decode). Adapters may ignore it.
|
|
38
|
+
*/
|
|
39
|
+
export interface UploadAdapterOptions {
|
|
40
|
+
readonly signal?: AbortSignal;
|
|
41
|
+
}
|
|
42
|
+
export type UploadAdapter = (file: File, options?: UploadAdapterOptions) => Promise<UploadResult>;
|
|
35
43
|
export interface AssetManagerOptions {
|
|
36
44
|
readonly uploader: UploadAdapter;
|
|
37
45
|
readonly maxFileSize?: number;
|
package/dist/types.d.cts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.cts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,SAAS;
|
|
1
|
+
{"version":3,"file":"types.d.cts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
CHANGED
|
@@ -31,7 +31,15 @@ export interface UploadResult {
|
|
|
31
31
|
*/
|
|
32
32
|
readonly tags?: readonly string[];
|
|
33
33
|
}
|
|
34
|
-
|
|
34
|
+
/**
|
|
35
|
+
* Options passed to an {@link UploadAdapter}. Currently carries an
|
|
36
|
+
* optional `AbortSignal` so a cancelled upload batch can short-circuit
|
|
37
|
+
* the adapter (network request, image decode). Adapters may ignore it.
|
|
38
|
+
*/
|
|
39
|
+
export interface UploadAdapterOptions {
|
|
40
|
+
readonly signal?: AbortSignal;
|
|
41
|
+
}
|
|
42
|
+
export type UploadAdapter = (file: File, options?: UploadAdapterOptions) => Promise<UploadResult>;
|
|
35
43
|
export interface AssetManagerOptions {
|
|
36
44
|
readonly uploader: UploadAdapter;
|
|
37
45
|
readonly maxFileSize?: number;
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,SAAS;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/dist/ui/AssetBrowser.cjs
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
"use client";
|
|
2
3
|
var __webpack_require__ = {};
|
|
3
4
|
(()=>{
|
|
4
5
|
__webpack_require__.d = (exports1, definition)=>{
|
|
@@ -29,6 +30,7 @@ __webpack_require__.d(__webpack_exports__, {
|
|
|
29
30
|
const card_namespaceObject = require("@anvilkit/ui/card");
|
|
30
31
|
const input_namespaceObject = require("@anvilkit/ui/input");
|
|
31
32
|
const external_react_namespaceObject = require("react");
|
|
33
|
+
const external_react_dom_namespaceObject = require("react-dom");
|
|
32
34
|
const external_infer_kind_cjs_namespaceObject = require("../infer-kind.cjs");
|
|
33
35
|
const KIND_FILTERS = [
|
|
34
36
|
"image",
|
|
@@ -50,22 +52,40 @@ function AssetBrowser({ assets, onInsert, onDelete, onReplace, onEdit, searchEna
|
|
|
50
52
|
const [pageLimit, setPageLimit] = external_react_namespaceObject.useState(pageSize);
|
|
51
53
|
const buttonRefs = external_react_namespaceObject.useRef([]);
|
|
52
54
|
const scrollContainerRef = external_react_namespaceObject.useRef(null);
|
|
55
|
+
const scrollFrameRef = external_react_namespaceObject.useRef(null);
|
|
56
|
+
const pendingScrollTopRef = external_react_namespaceObject.useRef(0);
|
|
57
|
+
external_react_namespaceObject.useEffect(()=>()=>{
|
|
58
|
+
if (null !== scrollFrameRef.current && "function" == typeof cancelAnimationFrame) cancelAnimationFrame(scrollFrameRef.current);
|
|
59
|
+
}, []);
|
|
60
|
+
const searchIndex = external_react_namespaceObject.useMemo(()=>{
|
|
61
|
+
if (!searchEnabled) return null;
|
|
62
|
+
return assets.map((asset)=>({
|
|
63
|
+
asset,
|
|
64
|
+
kind: (0, external_infer_kind_cjs_namespaceObject.inferAssetKind)(asset),
|
|
65
|
+
haystack: [
|
|
66
|
+
asset.id,
|
|
67
|
+
asset.name ?? "",
|
|
68
|
+
asset.meta?.mimeType ?? "",
|
|
69
|
+
...asset.tags ?? []
|
|
70
|
+
].join("\u0000").toLowerCase()
|
|
71
|
+
}));
|
|
72
|
+
}, [
|
|
73
|
+
assets,
|
|
74
|
+
searchEnabled
|
|
75
|
+
]);
|
|
53
76
|
const filteredAssets = external_react_namespaceObject.useMemo(()=>{
|
|
54
|
-
if (!searchEnabled) return assets;
|
|
77
|
+
if (!searchEnabled || null === searchIndex) return assets;
|
|
55
78
|
const lower = query.trim().toLowerCase();
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
if ("" === lower)
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
if (asset.meta?.mimeType?.toLowerCase().includes(lower)) return true;
|
|
64
|
-
if (asset.tags?.some((tag)=>tag.toLowerCase().includes(lower))) return true;
|
|
65
|
-
return false;
|
|
66
|
-
});
|
|
79
|
+
const hasKindFilter = activeKinds.length > 0;
|
|
80
|
+
if ("" === lower && !hasKindFilter) return assets;
|
|
81
|
+
const result = [];
|
|
82
|
+
for (const entry of searchIndex)if (!hasKindFilter || activeKinds.includes(entry.kind)) {
|
|
83
|
+
if ("" === lower || entry.haystack.includes(lower)) result.push(entry.asset);
|
|
84
|
+
}
|
|
85
|
+
return result;
|
|
67
86
|
}, [
|
|
68
87
|
assets,
|
|
88
|
+
searchIndex,
|
|
69
89
|
activeKinds,
|
|
70
90
|
query,
|
|
71
91
|
searchEnabled
|
|
@@ -87,19 +107,27 @@ function AssetBrowser({ assets, onInsert, onDelete, onReplace, onEdit, searchEna
|
|
|
87
107
|
function moveFocus(nextIndex) {
|
|
88
108
|
if (0 === total) return;
|
|
89
109
|
const clampedIndex = Math.max(0, Math.min(nextIndex, total - 1));
|
|
90
|
-
setActiveIndex(clampedIndex);
|
|
91
110
|
if (isVirtualized && scrollContainerRef.current) {
|
|
92
111
|
const targetTop = clampedIndex * itemHeight;
|
|
93
112
|
const targetBottom = targetTop + itemHeight;
|
|
94
113
|
const viewTop = scrollContainerRef.current.scrollTop;
|
|
95
|
-
|
|
96
|
-
if (targetTop < viewTop)
|
|
97
|
-
else if (targetBottom >
|
|
98
|
-
|
|
99
|
-
|
|
114
|
+
let nextScrollTop = viewTop;
|
|
115
|
+
if (targetTop < viewTop) nextScrollTop = targetTop;
|
|
116
|
+
else if (targetBottom > viewTop + maxHeight) nextScrollTop = targetBottom - maxHeight;
|
|
117
|
+
if (null !== scrollFrameRef.current && "function" == typeof cancelAnimationFrame) {
|
|
118
|
+
cancelAnimationFrame(scrollFrameRef.current);
|
|
119
|
+
scrollFrameRef.current = null;
|
|
120
|
+
}
|
|
121
|
+
pendingScrollTopRef.current = nextScrollTop;
|
|
122
|
+
(0, external_react_dom_namespaceObject.flushSync)(()=>{
|
|
123
|
+
setActiveIndex(clampedIndex);
|
|
124
|
+
setScrollTop(nextScrollTop);
|
|
100
125
|
});
|
|
126
|
+
scrollContainerRef.current.scrollTop = nextScrollTop;
|
|
127
|
+
buttonRefs.current[clampedIndex]?.focus();
|
|
101
128
|
return;
|
|
102
129
|
}
|
|
130
|
+
setActiveIndex(clampedIndex);
|
|
103
131
|
buttonRefs.current[clampedIndex]?.focus();
|
|
104
132
|
}
|
|
105
133
|
function toggleKind(kind) {
|
|
@@ -230,7 +258,14 @@ function AssetBrowser({ assets, onInsert, onDelete, onReplace, onEdit, searchEna
|
|
|
230
258
|
return /*#__PURE__*/ external_react_namespaceObject.createElement(card_namespaceObject.Card, null, /*#__PURE__*/ external_react_namespaceObject.createElement(card_namespaceObject.CardHeader, null, /*#__PURE__*/ external_react_namespaceObject.createElement(card_namespaceObject.CardTitle, null, "Asset browser"), /*#__PURE__*/ external_react_namespaceObject.createElement(card_namespaceObject.CardDescription, null, "Validated assets currently registered in memory.")), /*#__PURE__*/ external_react_namespaceObject.createElement(card_namespaceObject.CardContent, null, filterRow, /*#__PURE__*/ external_react_namespaceObject.createElement("div", {
|
|
231
259
|
"data-asset-manager-virtual": true,
|
|
232
260
|
onScroll: (event)=>{
|
|
233
|
-
|
|
261
|
+
const next = event.currentTarget.scrollTop;
|
|
262
|
+
if ("function" != typeof requestAnimationFrame) return void setScrollTop(next);
|
|
263
|
+
pendingScrollTopRef.current = next;
|
|
264
|
+
if (null !== scrollFrameRef.current) return;
|
|
265
|
+
scrollFrameRef.current = requestAnimationFrame(()=>{
|
|
266
|
+
scrollFrameRef.current = null;
|
|
267
|
+
setScrollTop(pendingScrollTopRef.current);
|
|
268
|
+
});
|
|
234
269
|
},
|
|
235
270
|
ref: scrollContainerRef,
|
|
236
271
|
style: {
|