@oomol-lab/open-flow 0.1.0-beta.89 → 0.1.0-beta.90
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 +29 -0
- package/dist/browser/{FlowCanvas-SqPUBqze.js → FlowCanvas-C4iuvVKB.js} +2 -2
- package/dist/browser/{exportPng-CLZKdNzR.js → exportPng-DMsB9ku_.js} +4 -4
- package/dist/browser/{flowChanges-CnOOPJJR.js → flowChanges-SKYJBr6X.js} +12 -11
- package/dist/browser/{flowWorkspace-d9Ef-aRK.js → flowWorkspace-4UHRaHcz.js} +10 -7
- package/dist/browser/{markdownContent-D0BBrFcF.js → markdownContent-B75ojl0E.js} +1 -1
- package/dist/browser/preview.css +14 -5
- package/dist/browser/preview.d.ts +4 -1
- package/dist/browser/preview.js +397 -95
- package/dist/browser/workbench-contract.d.ts +3 -0
- package/dist/browser/workbench.css +14 -5
- package/dist/browser/workbench.js +12 -9
- package/dist/browser/{wrapLayout-BB_qwy3k.js → wrapLayout-DU5HG1qH.js} +371 -71
- package/dist/command/index.js +13 -13
- package/dist/common/cache.d.ts +7 -0
- package/dist/common/catalogCache.d.ts +3 -7
- package/dist/common/control-api-conformance.js +10 -9
- package/dist/common/control-api.d.ts +3 -1
- package/dist/common/control-api.js +10 -9
- package/dist/common/mcp.js +10 -9
- package/dist/common/provider-icons.d.ts +35 -0
- package/dist/common/provider-icons.js +134 -0
- package/dist/render/browser/runtime.css +14 -5
- package/dist/render/browser/runtime.js +667 -365
- package/dist/render/common/png.d.ts +7 -0
- package/dist/render/node/index.d.ts +10 -2
- package/dist/render/node/index.js +1284 -37
- package/dist/render/node/licenses.md +24 -0
- package/package.json +5 -1
- package/src/base/common/cache.ts +8 -0
- package/src/connector/common/providerIconCache.ts +191 -0
- package/src/control/common/api.ts +10 -3
- package/src/control/common/catalogCache.ts +19 -11
package/dist/browser/preview.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { a as __toCommonJS, n as __esmMin, o as __toESM, r as __exportAll, t as __commonJSMin } from "./rolldown-runtime-CEgmsyvS.js";
|
|
2
2
|
import { _ as readonlyVal, a as isPlainObject$2, c as I18nProvider, d as useTranslate, f as useVal, g as derive, h as compute, i as isBoolean$1, l as useI18n, m as combine, n as pasteVideoLink, o as isString$1, p as attachSetter, r as isArray$2, s as toPlainObject, u as useLang, v as strictEqual, y as val } from "./videoLink-NAWDmBtf.js";
|
|
3
3
|
import * as m$4 from "react";
|
|
4
|
-
import reactExports, { Children, Fragment, Suspense, createContext, createElement, forwardRef, isValidElement, lazy, memo, useCallback, useContext, useEffect, useId, useImperativeHandle, useLayoutEffect, useMemo, useReducer, useRef, useState
|
|
4
|
+
import reactExports, { Children, Fragment, Suspense, createContext, createElement, forwardRef, isValidElement, lazy, memo, useCallback, useContext, useEffect, useId, useImperativeHandle, useLayoutEffect, useMemo, useReducer, useRef, useState } from "react";
|
|
5
5
|
import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
|
|
6
6
|
import * as ReactDOM from "react-dom";
|
|
7
7
|
import { createPortal, flushSync } from "react-dom";
|
|
@@ -66,6 +66,299 @@ function useIconifyCollectionLoader() {
|
|
|
66
66
|
/** Resource selection only; visual styling remains owned by theme.css. */
|
|
67
67
|
var IconThemeContext = createContext("light");
|
|
68
68
|
//#endregion
|
|
69
|
+
//#region src/connector/common/providerIconCache.ts
|
|
70
|
+
var defaultMaxAgeMs = 864e5;
|
|
71
|
+
var dataUrl = (entry) => `data:${entry.contentType};base64,${entry.body}`;
|
|
72
|
+
function decodeRecord(value) {
|
|
73
|
+
if (value == null || typeof value !== "object") return;
|
|
74
|
+
const v = value;
|
|
75
|
+
if (v.formatVersion !== 1 || typeof v.sourceUrl !== "string" || !(v.spriteVersion === null || typeof v.spriteVersion === "string") || typeof v.contentType !== "string" || !/^image\/[\w.+-]+$/i.test(v.contentType) || typeof v.body !== "string" || !v.body || v.body.length % 4 !== 0 || !/^[A-Za-z0-9+/]*={0,2}$/.test(v.body) || !(v.etag === null || typeof v.etag === "string") || !Number.isFinite(v.validatedAt) || v.validatedAt < 0 || !(v.maxAgeMs === null || Number.isFinite(v.maxAgeMs) && v.maxAgeMs >= 0)) return;
|
|
76
|
+
return v;
|
|
77
|
+
}
|
|
78
|
+
function encodeBytes(bytes) {
|
|
79
|
+
let text = "";
|
|
80
|
+
for (let index = 0; index < bytes.length; index += 8192) text += String.fromCharCode(...bytes.subarray(index, index + 8192));
|
|
81
|
+
return btoa(text);
|
|
82
|
+
}
|
|
83
|
+
function freshness(response, immutable, previous) {
|
|
84
|
+
const control = response.headers.get("cache-control") ?? "";
|
|
85
|
+
if (/\bno-cache\b/i.test(control)) return 0;
|
|
86
|
+
if (immutable) return null;
|
|
87
|
+
const maxAge = /(?:^|,)\s*max-age\s*=\s*"?(\d+)/i.exec(control);
|
|
88
|
+
if (maxAge) return Math.max(0, Number(maxAge[1]) * 1e3 - (Number(response.headers.get("age")) || 0) * 1e3);
|
|
89
|
+
const expires = Date.parse(response.headers.get("expires") ?? "");
|
|
90
|
+
if (Number.isFinite(expires)) return Math.max(0, expires - Date.parse(response.headers.get("date") ?? (/* @__PURE__ */ new Date()).toUTCString()));
|
|
91
|
+
return previous?.maxAgeMs ?? defaultMaxAgeMs;
|
|
92
|
+
}
|
|
93
|
+
/** Complete image responses in bounded, identity-checked slots; no catalog entities live here. */
|
|
94
|
+
var ProviderIconCache = class {
|
|
95
|
+
#memory = /* @__PURE__ */ new Map();
|
|
96
|
+
#pending = /* @__PURE__ */ new Map();
|
|
97
|
+
#targets = /* @__PURE__ */ new Map();
|
|
98
|
+
#writes = /* @__PURE__ */ new Map();
|
|
99
|
+
constructor(options) {
|
|
100
|
+
this.options = options;
|
|
101
|
+
if (!options.scope.trim()) throw new TypeError("Provider icon cache scope must be nonempty.");
|
|
102
|
+
}
|
|
103
|
+
get(request, options = {}) {
|
|
104
|
+
if (request.url.startsWith("data:image/")) return Promise.resolve(request.url);
|
|
105
|
+
let protocol;
|
|
106
|
+
try {
|
|
107
|
+
protocol = new URL(request.url).protocol;
|
|
108
|
+
} catch (error) {
|
|
109
|
+
return Promise.reject(error);
|
|
110
|
+
}
|
|
111
|
+
if (!["http:", "https:"].includes(protocol)) return Promise.reject(/* @__PURE__ */ new TypeError("Unsupported Provider icon URL."));
|
|
112
|
+
const slot = JSON.stringify([
|
|
113
|
+
"open-flow:provider-icons",
|
|
114
|
+
1,
|
|
115
|
+
this.options.scope,
|
|
116
|
+
request.kind,
|
|
117
|
+
request.kind === "sprite" ? request.theme : request.providerId
|
|
118
|
+
]);
|
|
119
|
+
const version = request.kind === "sprite" ? request.version : null;
|
|
120
|
+
const identity = JSON.stringify([request.url, version]);
|
|
121
|
+
const offline = options.allowNetwork === false || this.options.mode === "offline";
|
|
122
|
+
const key = JSON.stringify([
|
|
123
|
+
slot,
|
|
124
|
+
identity,
|
|
125
|
+
offline
|
|
126
|
+
]);
|
|
127
|
+
const pending = this.#pending.get(key);
|
|
128
|
+
if (pending) return pending;
|
|
129
|
+
if (!offline) this.#targets.set(slot, identity);
|
|
130
|
+
const promise = this.#load(slot, identity, request.url, version, offline).finally(() => this.#pending.delete(key));
|
|
131
|
+
this.#pending.set(key, promise);
|
|
132
|
+
return promise;
|
|
133
|
+
}
|
|
134
|
+
async #read(slot, url, version) {
|
|
135
|
+
const memory = this.#memory.get(slot);
|
|
136
|
+
if (this.#memory.has(slot) && (!memory || memory.sourceUrl === url && memory.spriteVersion === version)) return memory;
|
|
137
|
+
if (!this.options.delegate) return this.#memory.get(slot);
|
|
138
|
+
try {
|
|
139
|
+
const stored = await this.options.delegate.get(slot);
|
|
140
|
+
if (stored === void 0) return this.#memory.get(slot);
|
|
141
|
+
const entry = decodeRecord(stored);
|
|
142
|
+
if (entry) {
|
|
143
|
+
this.#memory.set(slot, entry);
|
|
144
|
+
return entry;
|
|
145
|
+
}
|
|
146
|
+
this.#memory.delete(slot);
|
|
147
|
+
await this.options.delegate.delete(slot);
|
|
148
|
+
} catch {
|
|
149
|
+
return this.#memory.get(slot);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
async #store(slot, identity, entry) {
|
|
153
|
+
const operation = (this.#writes.get(slot) ?? Promise.resolve()).then(async () => {
|
|
154
|
+
if (this.#targets.get(slot) !== identity) return;
|
|
155
|
+
this.#memory.set(slot, entry);
|
|
156
|
+
if (!this.options.delegate) return;
|
|
157
|
+
try {
|
|
158
|
+
if (entry) await this.options.delegate.set(slot, { ...entry });
|
|
159
|
+
else await this.options.delegate.delete(slot);
|
|
160
|
+
} catch {}
|
|
161
|
+
});
|
|
162
|
+
this.#writes.set(slot, operation);
|
|
163
|
+
try {
|
|
164
|
+
await operation;
|
|
165
|
+
} finally {
|
|
166
|
+
if (this.#writes.get(slot) === operation) this.#writes.delete(slot);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
async #load(slot, identity, url, version, offline) {
|
|
170
|
+
const stored = await this.#read(slot, url, version);
|
|
171
|
+
const cached = stored?.sourceUrl === url && stored.spriteVersion === version ? stored : void 0;
|
|
172
|
+
const age = cached == null ? Infinity : Date.now() - cached.validatedAt;
|
|
173
|
+
if (cached && (offline || this.options.mode !== "refresh" && age >= 0 && (cached.maxAgeMs === null || age < cached.maxAgeMs))) return dataUrl(cached);
|
|
174
|
+
if (offline) throw new Error(`Provider icon is not cached: ${url}`);
|
|
175
|
+
const response = await (this.options.fetch ?? globalThis.fetch)(url, {
|
|
176
|
+
credentials: "omit",
|
|
177
|
+
referrerPolicy: "no-referrer",
|
|
178
|
+
signal: AbortSignal.timeout(15e3),
|
|
179
|
+
headers: cached?.etag ? { "if-none-match": cached.etag } : {}
|
|
180
|
+
});
|
|
181
|
+
if (response.status !== 304 && !response.ok) throw new Error(`Could not load Provider icon: ${response.status}`);
|
|
182
|
+
if (response.status === 304 && !cached) throw new Error("Provider icon returned 304 without a cached image.");
|
|
183
|
+
const contentType = response.status === 304 ? cached.contentType : response.headers.get("content-type")?.split(";")[0]?.trim().toLowerCase();
|
|
184
|
+
if (!contentType || !/^image\/[\w.+-]+$/i.test(contentType)) throw new Error("Provider icon response is not an image.");
|
|
185
|
+
const body = response.status === 304 ? cached.body : encodeBytes(new Uint8Array(await response.arrayBuffer()));
|
|
186
|
+
if (!body) throw new Error("Provider icon response is empty.");
|
|
187
|
+
const entry = {
|
|
188
|
+
formatVersion: 1,
|
|
189
|
+
sourceUrl: url,
|
|
190
|
+
spriteVersion: version,
|
|
191
|
+
contentType,
|
|
192
|
+
body,
|
|
193
|
+
etag: response.headers.get("etag") ?? (response.status === 304 ? cached.etag : null),
|
|
194
|
+
validatedAt: Date.now(),
|
|
195
|
+
maxAgeMs: freshness(response, version !== null, response.status === 304 ? cached : void 0)
|
|
196
|
+
};
|
|
197
|
+
await this.#store(slot, identity, /\bno-store\b/i.test(response.headers.get("cache-control") ?? "") ? void 0 : entry);
|
|
198
|
+
return dataUrl(entry);
|
|
199
|
+
}
|
|
200
|
+
};
|
|
201
|
+
//#endregion
|
|
202
|
+
//#region src/ui/browser/icons/providerIconResource.ts
|
|
203
|
+
var ProviderIconCacheContext = createContext(void 0);
|
|
204
|
+
/** IDB holds the same opaque JSON records as a host's disk delegate. */
|
|
205
|
+
function indexedDbIconDelegate() {
|
|
206
|
+
let database;
|
|
207
|
+
function open() {
|
|
208
|
+
database ??= new Promise((resolve, reject) => {
|
|
209
|
+
const request = indexedDB.open("open-flow-provider-icons", 1);
|
|
210
|
+
request.addEventListener("upgradeneeded", () => request.result.createObjectStore("icons"), { once: true });
|
|
211
|
+
request.addEventListener("error", () => reject(request.error), { once: true });
|
|
212
|
+
request.addEventListener("blocked", () => reject(/* @__PURE__ */ new Error("Provider icon cache is blocked.")), { once: true });
|
|
213
|
+
request.addEventListener("success", () => {
|
|
214
|
+
const db = request.result;
|
|
215
|
+
db.addEventListener("versionchange", () => {
|
|
216
|
+
db.close();
|
|
217
|
+
database = void 0;
|
|
218
|
+
}, { once: true });
|
|
219
|
+
resolve(db);
|
|
220
|
+
}, { once: true });
|
|
221
|
+
}).catch((error) => {
|
|
222
|
+
database = void 0;
|
|
223
|
+
throw error;
|
|
224
|
+
});
|
|
225
|
+
return database;
|
|
226
|
+
}
|
|
227
|
+
async function transaction(mode, operation) {
|
|
228
|
+
const db = await open();
|
|
229
|
+
return new Promise((resolve, reject) => {
|
|
230
|
+
const tx = db.transaction("icons", mode);
|
|
231
|
+
const request = operation(tx.objectStore("icons"));
|
|
232
|
+
tx.addEventListener("complete", () => resolve(request.result), { once: true });
|
|
233
|
+
tx.addEventListener("abort", () => reject(tx.error ?? request.error), { once: true });
|
|
234
|
+
tx.addEventListener("error", () => reject(tx.error ?? request.error), { once: true });
|
|
235
|
+
});
|
|
236
|
+
}
|
|
237
|
+
return {
|
|
238
|
+
get: (key) => transaction("readonly", (store) => store.get(key)),
|
|
239
|
+
set: async (key, value) => {
|
|
240
|
+
await transaction("readwrite", (store) => store.put(value, key));
|
|
241
|
+
},
|
|
242
|
+
delete: async (key) => {
|
|
243
|
+
await transaction("readwrite", (store) => store.delete(key));
|
|
244
|
+
}
|
|
245
|
+
};
|
|
246
|
+
}
|
|
247
|
+
var browserCache;
|
|
248
|
+
function defaultBrowserIconCache() {
|
|
249
|
+
return browserCache ??= new ProviderIconCache({
|
|
250
|
+
scope: "browser",
|
|
251
|
+
delegate: indexedDbIconDelegate()
|
|
252
|
+
});
|
|
253
|
+
}
|
|
254
|
+
function useProviderIconCache() {
|
|
255
|
+
return useContext(ProviderIconCacheContext) ?? defaultBrowserIconCache();
|
|
256
|
+
}
|
|
257
|
+
var loading = { status: "loading" };
|
|
258
|
+
function createIconResource(cache, request, ready) {
|
|
259
|
+
const state = val(ready ?? loading);
|
|
260
|
+
let pending;
|
|
261
|
+
return {
|
|
262
|
+
state,
|
|
263
|
+
refresh() {
|
|
264
|
+
if (pending) return pending;
|
|
265
|
+
const previous = state.value.status === "loaded" ? state.value : void 0;
|
|
266
|
+
if (previous) state.set({
|
|
267
|
+
...previous,
|
|
268
|
+
refreshing: true
|
|
269
|
+
});
|
|
270
|
+
else if (state.value.status === "failed") state.set(loading);
|
|
271
|
+
pending = (async () => {
|
|
272
|
+
let image;
|
|
273
|
+
try {
|
|
274
|
+
const url = await cache.get(request);
|
|
275
|
+
if (previous?.url === url) {
|
|
276
|
+
state.set({
|
|
277
|
+
...previous,
|
|
278
|
+
refreshing: false
|
|
279
|
+
});
|
|
280
|
+
return;
|
|
281
|
+
}
|
|
282
|
+
image = new Image();
|
|
283
|
+
image.src = url;
|
|
284
|
+
await image.decode();
|
|
285
|
+
state.set({
|
|
286
|
+
status: "loaded",
|
|
287
|
+
url,
|
|
288
|
+
image
|
|
289
|
+
});
|
|
290
|
+
} catch {
|
|
291
|
+
if (image) image.src = "";
|
|
292
|
+
state.set(previous ? {
|
|
293
|
+
...previous,
|
|
294
|
+
refreshing: false
|
|
295
|
+
} : { status: "failed" });
|
|
296
|
+
}
|
|
297
|
+
})().finally(() => {
|
|
298
|
+
pending = void 0;
|
|
299
|
+
});
|
|
300
|
+
return pending;
|
|
301
|
+
}
|
|
302
|
+
};
|
|
303
|
+
}
|
|
304
|
+
var resources$1 = /* @__PURE__ */ new WeakMap();
|
|
305
|
+
/** Components read ready state synchronously; only the shared owner fetches and decodes. */
|
|
306
|
+
function useProviderIconResource(request, crop) {
|
|
307
|
+
const cache = useProviderIconCache();
|
|
308
|
+
const slot = JSON.stringify([request.kind, request.kind === "sprite" ? request.theme : request.providerId]);
|
|
309
|
+
const identity = JSON.stringify([
|
|
310
|
+
slot,
|
|
311
|
+
request.url,
|
|
312
|
+
request.kind === "sprite" ? request.version : null
|
|
313
|
+
]);
|
|
314
|
+
const previous = useRef();
|
|
315
|
+
const resource = useMemo(() => {
|
|
316
|
+
let slots = resources$1.get(cache);
|
|
317
|
+
if (!slots) {
|
|
318
|
+
slots = /* @__PURE__ */ new Map();
|
|
319
|
+
resources$1.set(cache, slots);
|
|
320
|
+
}
|
|
321
|
+
let current = slots.get(slot);
|
|
322
|
+
if (current?.identity !== identity) {
|
|
323
|
+
const value = previous.current?.identity === identity ? previous.current.resource.state.value : void 0;
|
|
324
|
+
current = {
|
|
325
|
+
identity,
|
|
326
|
+
resource: createIconResource(cache, request, value?.status === "loaded" ? value : void 0)
|
|
327
|
+
};
|
|
328
|
+
slots.set(slot, current);
|
|
329
|
+
}
|
|
330
|
+
previous.current = current;
|
|
331
|
+
return current.resource;
|
|
332
|
+
}, [cache, identity]);
|
|
333
|
+
const state = useVal(resource.state);
|
|
334
|
+
useEffect(() => {
|
|
335
|
+
resource.refresh();
|
|
336
|
+
}, [resource]);
|
|
337
|
+
return useMemo(() => {
|
|
338
|
+
if (state.status !== "loaded" || !crop) return state;
|
|
339
|
+
const canvas = document.createElement("canvas");
|
|
340
|
+
try {
|
|
341
|
+
canvas.width = canvas.height = crop.size;
|
|
342
|
+
const context = canvas.getContext("2d");
|
|
343
|
+
if (!context) throw new Error("Could not crop the Provider icon.");
|
|
344
|
+
context.drawImage(state.image, crop.x, crop.y, crop.size, crop.size, 0, 0, crop.size, crop.size);
|
|
345
|
+
return {
|
|
346
|
+
...state,
|
|
347
|
+
url: canvas.toDataURL("image/png")
|
|
348
|
+
};
|
|
349
|
+
} catch {
|
|
350
|
+
return { status: "failed" };
|
|
351
|
+
} finally {
|
|
352
|
+
canvas.width = canvas.height = 0;
|
|
353
|
+
}
|
|
354
|
+
}, [
|
|
355
|
+
state,
|
|
356
|
+
crop?.x,
|
|
357
|
+
crop?.y,
|
|
358
|
+
crop?.size
|
|
359
|
+
]);
|
|
360
|
+
}
|
|
361
|
+
//#endregion
|
|
69
362
|
//#region ../../node_modules/.bun/clsx@2.1.1/node_modules/clsx/dist/clsx.mjs
|
|
70
363
|
function r$1(e) {
|
|
71
364
|
var t, f, n = "";
|
|
@@ -33742,9 +34035,10 @@ var Zap = createLucideIcon("Zap", [["path", {
|
|
|
33742
34035
|
key: "1xq2db"
|
|
33743
34036
|
}]]);
|
|
33744
34037
|
var ContentIcon_module_default = {
|
|
33745
|
-
img: "
|
|
33746
|
-
|
|
33747
|
-
|
|
34038
|
+
img: "ContentIcon_img_e2c99",
|
|
34039
|
+
pending: "ContentIcon_pending_e2c99",
|
|
34040
|
+
initials: "ContentIcon_initials_e2c99",
|
|
34041
|
+
sprite: "ContentIcon_sprite_e2c99"
|
|
33748
34042
|
};
|
|
33749
34043
|
//#endregion
|
|
33750
34044
|
//#region src/connector/common/providerIconSprite.ts
|
|
@@ -33988,60 +34282,8 @@ function generateSvgDataUri(width, height, rawIcon, color) {
|
|
|
33988
34282
|
return `data:image/svg+xml;utf8,${encodeSvgForCss(svg)}`;
|
|
33989
34283
|
}
|
|
33990
34284
|
//#endregion
|
|
33991
|
-
//#region src/ui/browser/icons/spriteResource.ts
|
|
33992
|
-
function createResource(url) {
|
|
33993
|
-
let status = "loading";
|
|
33994
|
-
let started = false;
|
|
33995
|
-
const listeners = /* @__PURE__ */ new Set();
|
|
33996
|
-
return {
|
|
33997
|
-
getSnapshot: () => status,
|
|
33998
|
-
subscribe(listener) {
|
|
33999
|
-
listeners.add(listener);
|
|
34000
|
-
if (!started) {
|
|
34001
|
-
started = true;
|
|
34002
|
-
const finish = (next) => {
|
|
34003
|
-
status = next;
|
|
34004
|
-
for (const notify of listeners) notify();
|
|
34005
|
-
};
|
|
34006
|
-
if (typeof Image == "undefined") finish("failed");
|
|
34007
|
-
else {
|
|
34008
|
-
const image = new Image();
|
|
34009
|
-
const settle = (next) => {
|
|
34010
|
-
image.removeEventListener("load", loaded);
|
|
34011
|
-
image.removeEventListener("error", failed);
|
|
34012
|
-
finish(next);
|
|
34013
|
-
};
|
|
34014
|
-
const loaded = () => settle("loaded");
|
|
34015
|
-
const failed = () => settle("failed");
|
|
34016
|
-
image.addEventListener("load", loaded, { once: true });
|
|
34017
|
-
image.addEventListener("error", failed, { once: true });
|
|
34018
|
-
image.referrerPolicy = "no-referrer";
|
|
34019
|
-
image.src = url;
|
|
34020
|
-
}
|
|
34021
|
-
}
|
|
34022
|
-
return () => {
|
|
34023
|
-
listeners.delete(listener);
|
|
34024
|
-
};
|
|
34025
|
-
}
|
|
34026
|
-
};
|
|
34027
|
-
}
|
|
34028
|
-
var resources$1 = /* @__PURE__ */ new Map();
|
|
34029
|
-
function spriteResource(url) {
|
|
34030
|
-
let resource = resources$1.get(url);
|
|
34031
|
-
if (!resource) {
|
|
34032
|
-
resource = createResource(url);
|
|
34033
|
-
resources$1.set(url, resource);
|
|
34034
|
-
}
|
|
34035
|
-
return resource;
|
|
34036
|
-
}
|
|
34037
|
-
var serverSnapshot = () => "loading";
|
|
34038
|
-
function useSpriteStatus(url) {
|
|
34039
|
-
const resource = spriteResource(url);
|
|
34040
|
-
return useSyncExternalStore(resource.subscribe, resource.getSnapshot, serverSnapshot);
|
|
34041
|
-
}
|
|
34042
|
-
//#endregion
|
|
34043
34285
|
//#region src/ui/browser/icons/ContentIcon.tsx
|
|
34044
|
-
/** Standalone image capture uses
|
|
34286
|
+
/** Standalone image capture crops sprites and uses cross-origin-readable images. */
|
|
34045
34287
|
var IconImageCrossOriginContext = createContext(void 0);
|
|
34046
34288
|
/** A bundled, theme-aware placeholder that does not load a remote icon. */
|
|
34047
34289
|
var placeholderIcon = "data:application/vnd.open-flow.placeholder-icon,";
|
|
@@ -34053,18 +34295,19 @@ var ContentIcon = ({ src, className, fallback = null, loading = "lazy", decoding
|
|
|
34053
34295
|
const result = useMemo(() => parseIconifyIcon(source), [source]);
|
|
34054
34296
|
const [error, setError] = useState();
|
|
34055
34297
|
const onError = () => setError(source);
|
|
34056
|
-
if (sprite) return
|
|
34298
|
+
if (sprite) return /* @__PURE__ */ jsx(SpriteIcon, {
|
|
34057
34299
|
className,
|
|
34058
34300
|
fallback,
|
|
34059
34301
|
loading,
|
|
34060
34302
|
decoding,
|
|
34061
|
-
|
|
34062
|
-
})
|
|
34303
|
+
sprite
|
|
34304
|
+
});
|
|
34305
|
+
if (image?.providerId) return /* @__PURE__ */ jsx(ProviderImage, {
|
|
34063
34306
|
className,
|
|
34064
34307
|
fallback,
|
|
34065
34308
|
loading,
|
|
34066
34309
|
decoding,
|
|
34067
|
-
|
|
34310
|
+
image
|
|
34068
34311
|
});
|
|
34069
34312
|
if (source === "data:application/vnd.open-flow.placeholder-icon,") return /* @__PURE__ */ jsx("i", {
|
|
34070
34313
|
"aria-hidden": "true",
|
|
@@ -34107,10 +34350,11 @@ var ContentIcon = ({ src, className, fallback = null, loading = "lazy", decoding
|
|
|
34107
34350
|
};
|
|
34108
34351
|
var initialsIconPrefix = "data:application/vnd.open-flow.initials,";
|
|
34109
34352
|
var imageIconPrefix = "data:application/vnd.open-flow.image-icon+json,";
|
|
34110
|
-
function imageIcon(source, fallback) {
|
|
34353
|
+
function imageIcon(source, fallback, providerId) {
|
|
34111
34354
|
return `${imageIconPrefix}${encodeURIComponent(JSON.stringify({
|
|
34112
34355
|
fallback,
|
|
34113
|
-
source
|
|
34356
|
+
source,
|
|
34357
|
+
...providerId == null ? {} : { providerId }
|
|
34114
34358
|
}))}`;
|
|
34115
34359
|
}
|
|
34116
34360
|
function parseImageIcon(src) {
|
|
@@ -34119,7 +34363,8 @@ function parseImageIcon(src) {
|
|
|
34119
34363
|
const value = JSON.parse(decodeURIComponent(src.slice(47)));
|
|
34120
34364
|
if (typeof value.fallback == "string" && typeof value.source == "string") return {
|
|
34121
34365
|
fallback: value.fallback,
|
|
34122
|
-
source: value.source
|
|
34366
|
+
source: value.source,
|
|
34367
|
+
...typeof value.providerId === "string" ? { providerId: value.providerId } : {}
|
|
34123
34368
|
};
|
|
34124
34369
|
} catch {
|
|
34125
34370
|
return;
|
|
@@ -34159,19 +34404,39 @@ function parseSpriteIcon(src) {
|
|
|
34159
34404
|
}
|
|
34160
34405
|
function SpriteIcon({ sprite, ...props }) {
|
|
34161
34406
|
const theme = useContext(IconThemeContext);
|
|
34407
|
+
const capture = useContext(IconImageCrossOriginContext) != null;
|
|
34162
34408
|
const { iconSprite: m, iconSpritePosition: p } = sprite;
|
|
34163
|
-
const
|
|
34164
|
-
|
|
34165
|
-
|
|
34409
|
+
const resource = useProviderIconResource({
|
|
34410
|
+
kind: "sprite",
|
|
34411
|
+
theme,
|
|
34412
|
+
url: theme == "dark" ? m.darkUrl : m.lightUrl,
|
|
34413
|
+
version: m.version
|
|
34414
|
+
}, capture ? {
|
|
34415
|
+
x: p.x,
|
|
34416
|
+
y: p.y,
|
|
34417
|
+
size: m.iconSize
|
|
34418
|
+
} : void 0);
|
|
34419
|
+
if (resource.status == "failed") return /* @__PURE__ */ jsx(ContentIcon, {
|
|
34166
34420
|
...props,
|
|
34167
34421
|
src: sprite.fallback
|
|
34168
34422
|
});
|
|
34423
|
+
if (resource.status === "loading") return /* @__PURE__ */ jsx(PendingIcon, {
|
|
34424
|
+
className: props.className,
|
|
34425
|
+
fallback: props.fallback
|
|
34426
|
+
});
|
|
34427
|
+
if (capture) return /* @__PURE__ */ jsx("img", {
|
|
34428
|
+
alt: "",
|
|
34429
|
+
className: clsx(ContentIcon_module_default.img, props.className),
|
|
34430
|
+
"data-render-pending": resource.refreshing || void 0,
|
|
34431
|
+
src: resource.url,
|
|
34432
|
+
decoding: "sync"
|
|
34433
|
+
});
|
|
34169
34434
|
return /* @__PURE__ */ jsx("span", {
|
|
34170
34435
|
"aria-hidden": "true",
|
|
34171
|
-
"data-render-pending":
|
|
34436
|
+
"data-render-pending": resource.refreshing || void 0,
|
|
34172
34437
|
className: clsx(ContentIcon_module_default.sprite, props.className),
|
|
34173
|
-
children:
|
|
34174
|
-
backgroundImage: `url(${JSON.stringify(url)})`,
|
|
34438
|
+
children: /* @__PURE__ */ jsx("span", { style: {
|
|
34439
|
+
backgroundImage: `url(${JSON.stringify(resource.url)})`,
|
|
34175
34440
|
width: `${m.width / m.iconSize * 100}%`,
|
|
34176
34441
|
height: `${m.height / m.iconSize * 100}%`,
|
|
34177
34442
|
left: `${-p.x / m.iconSize * 100}%`,
|
|
@@ -34179,6 +34444,40 @@ function SpriteIcon({ sprite, ...props }) {
|
|
|
34179
34444
|
} })
|
|
34180
34445
|
});
|
|
34181
34446
|
}
|
|
34447
|
+
function ProviderImage({ image, ...props }) {
|
|
34448
|
+
const resource = useProviderIconResource({
|
|
34449
|
+
kind: "image",
|
|
34450
|
+
providerId: image.providerId,
|
|
34451
|
+
url: image.source
|
|
34452
|
+
});
|
|
34453
|
+
if (resource.status === "failed") return /* @__PURE__ */ jsx(ContentIcon, {
|
|
34454
|
+
...props,
|
|
34455
|
+
src: image.fallback
|
|
34456
|
+
});
|
|
34457
|
+
if (resource.status === "loading") return /* @__PURE__ */ jsx(PendingIcon, {
|
|
34458
|
+
className: props.className,
|
|
34459
|
+
fallback: props.fallback
|
|
34460
|
+
});
|
|
34461
|
+
return /* @__PURE__ */ jsx("img", {
|
|
34462
|
+
alt: "",
|
|
34463
|
+
className: clsx(ContentIcon_module_default.img, props.className),
|
|
34464
|
+
"data-render-pending": resource.refreshing || void 0,
|
|
34465
|
+
src: resource.url,
|
|
34466
|
+
loading: props.loading,
|
|
34467
|
+
decoding: props.decoding
|
|
34468
|
+
});
|
|
34469
|
+
}
|
|
34470
|
+
function PendingIcon({ className, fallback }) {
|
|
34471
|
+
return /* @__PURE__ */ jsx("span", {
|
|
34472
|
+
"aria-hidden": "true",
|
|
34473
|
+
className: clsx(ContentIcon_module_default.pending, className),
|
|
34474
|
+
"data-render-pending": true,
|
|
34475
|
+
children: fallback ?? /* @__PURE__ */ jsx(ContentIcon, {
|
|
34476
|
+
src: "data:application/vnd.open-flow.placeholder-icon,",
|
|
34477
|
+
className
|
|
34478
|
+
})
|
|
34479
|
+
});
|
|
34480
|
+
}
|
|
34182
34481
|
var handle_module_default = {
|
|
34183
34482
|
wrapper: "handle_wrapper_c0108",
|
|
34184
34483
|
handle: "handle_handle_c0108",
|
|
@@ -65785,7 +66084,7 @@ function provider(value, metadata) {
|
|
|
65785
66084
|
//#region src/workbench/browser/runtime/providerIcon.ts
|
|
65786
66085
|
function providerIcon(provider) {
|
|
65787
66086
|
const source = provider.icon?.trim();
|
|
65788
|
-
const original = source ? imageIcon(source, placeholderIcon) : placeholderIcon;
|
|
66087
|
+
const original = source ? imageIcon(source, placeholderIcon, provider.serviceId) : placeholderIcon;
|
|
65789
66088
|
const appearance = providerIconAppearance(provider.iconSprite, provider.iconSpritePosition);
|
|
65790
66089
|
return appearance?.iconSprite && appearance.iconSpritePosition ? spriteIcon({
|
|
65791
66090
|
iconSprite: appearance.iconSprite,
|
|
@@ -120415,36 +120714,39 @@ function RevisionCanvas({ draft, presentation, theme, interactiveMode$, defaultI
|
|
|
120415
120714
|
//#endregion
|
|
120416
120715
|
//#region src/workbench/browser/runtime/openFlowPreview.tsx
|
|
120417
120716
|
/** Offline workflow preview. Use a React key to start a new layout/selection session. */
|
|
120418
|
-
function OpenFlowPreview({ draft, presentation, language, theme, defaultInteractiveMode, defaultDirection, defaultMiniMapExpanded, defaultInspectorOpen, defaultSelectedNodeIds, nodesDraggable = true, dottedBackground = true, layoutMotion = true, label, className }) {
|
|
120717
|
+
function OpenFlowPreview({ iconCache, draft, presentation, language, theme, defaultInteractiveMode, defaultDirection, defaultMiniMapExpanded, defaultInspectorOpen, defaultSelectedNodeIds, nodesDraggable = true, dottedBackground = true, layoutMotion = true, label, className }) {
|
|
120419
120718
|
const [i18n] = useState(() => createI18n(language));
|
|
120420
120719
|
useEffect(() => {
|
|
120421
120720
|
if (i18n.lang !== language) i18n.switchLang(language);
|
|
120422
120721
|
}, [i18n, language]);
|
|
120423
120722
|
useEffect(() => () => i18n.dispose(), [i18n]);
|
|
120424
|
-
return /* @__PURE__ */ jsx(
|
|
120425
|
-
value:
|
|
120426
|
-
children: /* @__PURE__ */ jsx(
|
|
120427
|
-
|
|
120428
|
-
children: /* @__PURE__ */ jsx(
|
|
120429
|
-
|
|
120430
|
-
"
|
|
120431
|
-
|
|
120432
|
-
|
|
120433
|
-
|
|
120434
|
-
|
|
120435
|
-
|
|
120436
|
-
|
|
120437
|
-
|
|
120438
|
-
|
|
120439
|
-
|
|
120440
|
-
|
|
120441
|
-
|
|
120442
|
-
|
|
120443
|
-
|
|
120444
|
-
|
|
120723
|
+
return /* @__PURE__ */ jsx(ProviderIconCacheContext.Provider, {
|
|
120724
|
+
value: iconCache,
|
|
120725
|
+
children: /* @__PURE__ */ jsx(IconThemeContext.Provider, {
|
|
120726
|
+
value: theme,
|
|
120727
|
+
children: /* @__PURE__ */ jsx(IconifyProvider, { children: /* @__PURE__ */ jsx(I18nProvider, {
|
|
120728
|
+
i18n,
|
|
120729
|
+
children: /* @__PURE__ */ jsx("div", {
|
|
120730
|
+
className: cn$1("open-flow-theme open-flow-workbench open-flow-preview", className),
|
|
120731
|
+
"data-theme": theme,
|
|
120732
|
+
children: /* @__PURE__ */ jsx(RevisionCanvas, {
|
|
120733
|
+
draft,
|
|
120734
|
+
presentation,
|
|
120735
|
+
theme,
|
|
120736
|
+
defaultInteractiveMode,
|
|
120737
|
+
defaultDirection,
|
|
120738
|
+
defaultMiniMapExpanded,
|
|
120739
|
+
defaultInspectorOpen,
|
|
120740
|
+
defaultSelectedNodeIds,
|
|
120741
|
+
nodesDraggable,
|
|
120742
|
+
layoutMotion,
|
|
120743
|
+
label,
|
|
120744
|
+
background: dottedBackground ? "dotted" : "none",
|
|
120745
|
+
showHeader: false
|
|
120746
|
+
})
|
|
120445
120747
|
})
|
|
120446
|
-
})
|
|
120447
|
-
})
|
|
120748
|
+
}) })
|
|
120749
|
+
})
|
|
120448
120750
|
});
|
|
120449
120751
|
}
|
|
120450
120752
|
//#endregion
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { ReactNode } from 'react';
|
|
2
|
+
import type { ProviderIconLoader } from '../common/provider-icons.js';
|
|
2
3
|
import type { WorkflowBundleImportResult } from '../common/control-api.js';
|
|
3
4
|
import type { FlowCatalogEvent, FlowChangeEvent } from './flow-notifications.js';
|
|
4
5
|
import type { WorkflowBundle } from '../common/flow-workflowBundle.js';
|
|
@@ -22,6 +23,8 @@ export interface WorkbenchActor {
|
|
|
22
23
|
readonly avatarUrl?: string;
|
|
23
24
|
}
|
|
24
25
|
export interface WorkbenchHost {
|
|
26
|
+
/** Optional shared Provider artwork cache; defaults to browser IndexedDB. */
|
|
27
|
+
readonly iconCache?: ProviderIconLoader;
|
|
25
28
|
/** Optional deployment-owned identity lookup. Return null for an unknown actor. */
|
|
26
29
|
readonly resolveActor?: (actorId: string, signal: AbortSignal) => Promise<WorkbenchActor | null>;
|
|
27
30
|
/** Cache deployment identity. The session id must be stable and non-secret. */
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
@charset "UTF-8";.
|
|
1
|
+
@charset "UTF-8";.ContentIcon_img_e2c99 {
|
|
2
2
|
width: 1em;
|
|
3
3
|
height: 1em;
|
|
4
4
|
vertical-align: middle;
|
|
@@ -6,7 +6,16 @@
|
|
|
6
6
|
object-fit: contain;
|
|
7
7
|
}
|
|
8
8
|
|
|
9
|
-
.
|
|
9
|
+
.ContentIcon_pending_e2c99 {
|
|
10
|
+
display: inline-flex;
|
|
11
|
+
width: 1em;
|
|
12
|
+
height: 1em;
|
|
13
|
+
align-items: center;
|
|
14
|
+
justify-content: center;
|
|
15
|
+
vertical-align: middle;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
.ContentIcon_initials_e2c99 {
|
|
10
19
|
display: inline-flex;
|
|
11
20
|
width: 1em;
|
|
12
21
|
height: 1em;
|
|
@@ -19,13 +28,13 @@
|
|
|
19
28
|
vertical-align: middle;
|
|
20
29
|
pointer-events: none;
|
|
21
30
|
}
|
|
22
|
-
.
|
|
31
|
+
.ContentIcon_initials_e2c99 > span {
|
|
23
32
|
font-size: 0.42em;
|
|
24
33
|
font-weight: 400;
|
|
25
34
|
line-height: 1;
|
|
26
35
|
}
|
|
27
36
|
|
|
28
|
-
.
|
|
37
|
+
.ContentIcon_sprite_e2c99 {
|
|
29
38
|
display: inline-block;
|
|
30
39
|
position: relative;
|
|
31
40
|
overflow: hidden;
|
|
@@ -35,7 +44,7 @@
|
|
|
35
44
|
vertical-align: middle;
|
|
36
45
|
pointer-events: none;
|
|
37
46
|
}
|
|
38
|
-
.
|
|
47
|
+
.ContentIcon_sprite_e2c99 > span {
|
|
39
48
|
position: absolute;
|
|
40
49
|
background-size: 100% 100%;
|
|
41
50
|
background-repeat: no-repeat;
|