@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.
Files changed (33) hide show
  1. package/README.md +29 -0
  2. package/dist/browser/{FlowCanvas-SqPUBqze.js → FlowCanvas-C4iuvVKB.js} +2 -2
  3. package/dist/browser/{exportPng-CLZKdNzR.js → exportPng-DMsB9ku_.js} +4 -4
  4. package/dist/browser/{flowChanges-CnOOPJJR.js → flowChanges-SKYJBr6X.js} +12 -11
  5. package/dist/browser/{flowWorkspace-d9Ef-aRK.js → flowWorkspace-4UHRaHcz.js} +10 -7
  6. package/dist/browser/{markdownContent-D0BBrFcF.js → markdownContent-B75ojl0E.js} +1 -1
  7. package/dist/browser/preview.css +14 -5
  8. package/dist/browser/preview.d.ts +4 -1
  9. package/dist/browser/preview.js +397 -95
  10. package/dist/browser/workbench-contract.d.ts +3 -0
  11. package/dist/browser/workbench.css +14 -5
  12. package/dist/browser/workbench.js +12 -9
  13. package/dist/browser/{wrapLayout-BB_qwy3k.js → wrapLayout-DU5HG1qH.js} +371 -71
  14. package/dist/command/index.js +13 -13
  15. package/dist/common/cache.d.ts +7 -0
  16. package/dist/common/catalogCache.d.ts +3 -7
  17. package/dist/common/control-api-conformance.js +10 -9
  18. package/dist/common/control-api.d.ts +3 -1
  19. package/dist/common/control-api.js +10 -9
  20. package/dist/common/mcp.js +10 -9
  21. package/dist/common/provider-icons.d.ts +35 -0
  22. package/dist/common/provider-icons.js +134 -0
  23. package/dist/render/browser/runtime.css +14 -5
  24. package/dist/render/browser/runtime.js +667 -365
  25. package/dist/render/common/png.d.ts +7 -0
  26. package/dist/render/node/index.d.ts +10 -2
  27. package/dist/render/node/index.js +1284 -37
  28. package/dist/render/node/licenses.md +24 -0
  29. package/package.json +5 -1
  30. package/src/base/common/cache.ts +8 -0
  31. package/src/connector/common/providerIconCache.ts +191 -0
  32. package/src/control/common/api.ts +10 -3
  33. package/src/control/common/catalogCache.ts +19 -11
@@ -8121,9 +8121,10 @@ var OpenFlowRenderer = (function(exports) {
8121
8121
  return [width, height];
8122
8122
  }
8123
8123
  var ContentIcon_module_default = {
8124
- img: "ContentIcon_img_4e5d2",
8125
- initials: "ContentIcon_initials_4e5d2",
8126
- sprite: "ContentIcon_sprite_4e5d2"
8124
+ img: "ContentIcon_img_e2c99",
8125
+ pending: "ContentIcon_pending_e2c99",
8126
+ initials: "ContentIcon_initials_e2c99",
8127
+ sprite: "ContentIcon_sprite_e2c99"
8127
8128
  };
8128
8129
  //#endregion
8129
8130
  //#region ../../node_modules/.bun/clsx@2.1.1/node_modules/clsx/dist/clsx.mjs
@@ -23610,312 +23611,8 @@ var OpenFlowRenderer = (function(exports) {
23610
23611
  /** Resource selection only; visual styling remains owned by theme.css. */
23611
23612
  var IconThemeContext = (0, import_react$4.createContext)("light");
23612
23613
  //#endregion
23613
- //#region src/ui/browser/icons/spriteResource.ts
23614
- function createResource(url) {
23615
- let status = "loading";
23616
- let started = false;
23617
- const listeners = /* @__PURE__ */ new Set();
23618
- return {
23619
- getSnapshot: () => status,
23620
- subscribe(listener) {
23621
- listeners.add(listener);
23622
- if (!started) {
23623
- started = true;
23624
- const finish = (next) => {
23625
- status = next;
23626
- for (const notify of listeners) notify();
23627
- };
23628
- if (typeof Image == "undefined") finish("failed");
23629
- else {
23630
- const image = new Image();
23631
- const settle = (next) => {
23632
- image.removeEventListener("load", loaded);
23633
- image.removeEventListener("error", failed);
23634
- finish(next);
23635
- };
23636
- const loaded = () => settle("loaded");
23637
- const failed = () => settle("failed");
23638
- image.addEventListener("load", loaded, { once: true });
23639
- image.addEventListener("error", failed, { once: true });
23640
- image.referrerPolicy = "no-referrer";
23641
- image.src = url;
23642
- }
23643
- }
23644
- return () => {
23645
- listeners.delete(listener);
23646
- };
23647
- }
23648
- };
23649
- }
23650
- var resources$1 = /* @__PURE__ */ new Map();
23651
- function spriteResource(url) {
23652
- let resource = resources$1.get(url);
23653
- if (!resource) {
23654
- resource = createResource(url);
23655
- resources$1.set(url, resource);
23656
- }
23657
- return resource;
23658
- }
23659
- var serverSnapshot = () => "loading";
23660
- function useSpriteStatus(url) {
23661
- const resource = spriteResource(url);
23662
- return (0, import_react$4.useSyncExternalStore)(resource.subscribe, resource.getSnapshot, serverSnapshot);
23663
- }
23664
- //#endregion
23665
- //#region src/ui/browser/icons/ContentIcon.tsx
23666
- /** Standalone image capture uses individual, cross-origin-readable images instead of sprites. */
23667
- var IconImageCrossOriginContext = (0, import_react$4.createContext)(void 0);
23668
- /** A bundled, theme-aware placeholder that does not load a remote icon. */
23669
- var placeholderIcon = "data:application/vnd.open-flow.placeholder-icon,";
23670
- var ContentIcon = ({ src, className, fallback = null, loading = "lazy", decoding = "async" }) => {
23671
- const crossOrigin = (0, import_react$4.useContext)(IconImageCrossOriginContext);
23672
- const sprite = (0, import_react$4.useMemo)(() => parseSpriteIcon(src), [src]);
23673
- const image = (0, import_react$4.useMemo)(() => parseImageIcon(src), [src]);
23674
- const source = image?.source ?? src;
23675
- const result = (0, import_react$4.useMemo)(() => parseIconifyIcon(source), [source]);
23676
- const [error, setError] = (0, import_react$4.useState)();
23677
- const onError = () => setError(source);
23678
- if (sprite) return crossOrigin ? /* @__PURE__ */ (0, import_jsx_runtime$2.jsx)(ContentIcon, {
23679
- className,
23680
- fallback,
23681
- loading,
23682
- decoding,
23683
- src: sprite.fallback
23684
- }) : /* @__PURE__ */ (0, import_jsx_runtime$2.jsx)(SpriteIcon, {
23685
- className,
23686
- fallback,
23687
- loading,
23688
- decoding,
23689
- sprite
23690
- });
23691
- if (source === "data:application/vnd.open-flow.placeholder-icon,") return /* @__PURE__ */ (0, import_jsx_runtime$2.jsx)("i", {
23692
- "aria-hidden": "true",
23693
- className: clsx("i-lucide-light:plug", className)
23694
- });
23695
- if (source?.startsWith(initialsIconPrefix)) {
23696
- if (crossOrigin && fallback != null) return /* @__PURE__ */ (0, import_jsx_runtime$2.jsx)(import_jsx_runtime$2.Fragment, { children: fallback });
23697
- return /* @__PURE__ */ (0, import_jsx_runtime$2.jsx)("span", {
23698
- "data-icon-kind": "initials",
23699
- "aria-hidden": "true",
23700
- className: clsx(ContentIcon_module_default.initials, className),
23701
- children: /* @__PURE__ */ (0, import_jsx_runtime$2.jsx)("span", { children: source.slice(initialsIconPrefix.length) })
23702
- });
23703
- }
23704
- if (!source) return fallback;
23705
- if (source === error && crossOrigin && fallback != null) return /* @__PURE__ */ (0, import_jsx_runtime$2.jsx)(import_jsx_runtime$2.Fragment, { children: fallback });
23706
- if (source === error) return image == null ? fallback : /* @__PURE__ */ (0, import_jsx_runtime$2.jsx)(ContentIcon, {
23707
- className,
23708
- fallback,
23709
- src: image.fallback,
23710
- loading,
23711
- decoding
23712
- });
23713
- return result ? /* @__PURE__ */ (0, import_jsx_runtime$2.jsx)(IconifyIcon, {
23714
- collection: result.collection,
23715
- icon: result.icon,
23716
- color: result.color,
23717
- className,
23718
- onError
23719
- }) : /* @__PURE__ */ (0, import_jsx_runtime$2.jsx)("img", {
23720
- className: clsx(ContentIcon_module_default.img, className),
23721
- src: source,
23722
- alt: "",
23723
- crossOrigin,
23724
- decoding,
23725
- loading,
23726
- referrerPolicy: "no-referrer",
23727
- onError
23728
- });
23729
- };
23730
- var initialsIconPrefix = "data:application/vnd.open-flow.initials,";
23731
- var imageIconPrefix = "data:application/vnd.open-flow.image-icon+json,";
23732
- function imageIcon(source, fallback) {
23733
- return `${imageIconPrefix}${encodeURIComponent(JSON.stringify({
23734
- fallback,
23735
- source
23736
- }))}`;
23737
- }
23738
- function parseImageIcon(src) {
23739
- if (!src?.startsWith(imageIconPrefix)) return;
23740
- try {
23741
- const value = JSON.parse(decodeURIComponent(src.slice(47)));
23742
- if (typeof value.fallback == "string" && typeof value.source == "string") return {
23743
- fallback: value.fallback,
23744
- source: value.source
23745
- };
23746
- } catch {
23747
- return;
23748
- }
23749
- }
23750
- function parseIconifyIcon(src) {
23751
- if (src && src.length > 2 && src[0] === ":" && src.endsWith(":")) {
23752
- const [, collection, icon, color] = src.split(":");
23753
- if (collection && icon) return {
23754
- collection,
23755
- icon,
23756
- color: color || "currentColor"
23757
- };
23758
- }
23759
- return null;
23760
- }
23761
- var spriteIconPrefix = "data:application/vnd.open-flow.sprite-icon+json,";
23762
- function spriteIcon(appearance, fallback) {
23763
- return `${spriteIconPrefix}${encodeURIComponent(JSON.stringify({
23764
- ...appearance,
23765
- fallback
23766
- }))}`;
23767
- }
23768
- function parseSpriteIcon(src) {
23769
- if (!src?.startsWith(spriteIconPrefix)) return;
23770
- try {
23771
- const value = JSON.parse(decodeURIComponent(src.slice(48)));
23772
- const appearance = providerIconAppearance(value?.iconSprite, value?.iconSpritePosition);
23773
- if (appearance.iconSprite && appearance.iconSpritePosition && typeof value.fallback == "string") return {
23774
- iconSprite: appearance.iconSprite,
23775
- iconSpritePosition: appearance.iconSpritePosition,
23776
- fallback: value.fallback
23777
- };
23778
- } catch {
23779
- return;
23780
- }
23781
- }
23782
- function SpriteIcon({ sprite, ...props }) {
23783
- const theme = (0, import_react$4.useContext)(IconThemeContext);
23784
- const { iconSprite: m, iconSpritePosition: p } = sprite;
23785
- const url = theme == "dark" ? m.darkUrl : m.lightUrl;
23786
- const status = useSpriteStatus(url);
23787
- if (status == "failed") return /* @__PURE__ */ (0, import_jsx_runtime$2.jsx)(ContentIcon, {
23788
- ...props,
23789
- src: sprite.fallback
23790
- });
23791
- return /* @__PURE__ */ (0, import_jsx_runtime$2.jsx)("span", {
23792
- "aria-hidden": "true",
23793
- "data-render-pending": status == "loading" || void 0,
23794
- className: clsx(ContentIcon_module_default.sprite, props.className),
23795
- children: status == "loaded" && /* @__PURE__ */ (0, import_jsx_runtime$2.jsx)("span", { style: {
23796
- backgroundImage: `url(${JSON.stringify(url)})`,
23797
- width: `${m.width / m.iconSize * 100}%`,
23798
- height: `${m.height / m.iconSize * 100}%`,
23799
- left: `${-p.x / m.iconSize * 100}%`,
23800
- top: `${-p.y / m.iconSize * 100}%`
23801
- } })
23802
- });
23803
- }
23804
- //#endregion
23805
- //#region ../../assets/logo/open-flow-dark.svg
23806
- var open_flow_dark_default = "data:image/svg+xml,%3csvg%20xmlns='http://www.w3.org/2000/svg'%20width='100'%20height='100'%20viewBox='0%200%20100%20100'%20role='img'%20aria-label='Open%20Flow'%3e%3cpath%20fill='%23e0e2e6'%20d='M32%2016H68Q84%2016%2084%2032V36H68C46%2036%2054%2056%2032%2056H16V32Q16%2016%2032%2016Z'/%3e%3cpath%20fill='%238c919a'%20d='M16%2068H32C54%2068%2046%2048%2068%2048H84V68Q84%2084%2068%2084H32Q16%2084%2016%2068Z'/%3e%3c/svg%3e";
23807
- //#endregion
23808
- //#region ../../assets/logo/open-flow-light.svg
23809
- var open_flow_light_default = "data:image/svg+xml,%3csvg%20xmlns='http://www.w3.org/2000/svg'%20width='100'%20height='100'%20viewBox='0%200%20100%20100'%20role='img'%20aria-label='Open%20Flow'%3e%3cpath%20fill='%2344474c'%20d='M32%2016H68Q84%2016%2084%2032V36H68C46%2036%2054%2056%2032%2056H16V32Q16%2016%2032%2016Z'/%3e%3cpath%20fill='%2393979f'%20d='M16%2068H32C54%2068%2046%2048%2068%2048H84V68Q84%2084%2068%2084H32Q16%2084%2016%2068Z'/%3e%3c/svg%3e";
23810
- //#endregion
23811
- //#region src/ui/browser/logo.tsx
23812
- function openFlowLogoSource(theme) {
23813
- return theme === "dark" ? open_flow_dark_default : open_flow_light_default;
23814
- }
23815
- //#endregion
23816
- //#region ../../node_modules/.bun/@wopjs+disposable@0.1.24/node_modules/@wopjs/disposable/dist/index.mjs
23817
- var isFn = (value) => !!(value && value.constructor && value.call && value.apply);
23818
- /**
23819
- * Check if a value is a {@link DisposableType}.
23820
- * @param value The value to check.
23821
- * @returns True if the value is a {@link DisposableType}, false otherwise.
23822
- */
23823
- var isDisposable = (value) => isFn(value) || isFn(value?.dispose);
23824
- /**
23825
- * Dispose a disposable object or a disposer function. Log the error if any.
23826
- * @param disposable A disposable object or a disposer function. Do nothing otherwise.
23827
- */
23828
- function dispose(disposable) {
23829
- try {
23830
- if (disposable) {
23831
- if (isFn(disposable.dispose)) disposable.dispose();
23832
- else if (isFn(disposable)) disposable();
23833
- }
23834
- } catch (e) {
23835
- console.error(e);
23836
- }
23837
- }
23838
- var isAbortable = (disposable) => isDisposable(disposable) && isFn(disposable.abortable);
23839
- /**
23840
- * Create a {@link DisposableStore} that manages {@link Disposer}s and {@link IDisposable}s.
23841
- *
23842
- * A {@link DisposableStore} is also a {@link Disposer}, which means it can be the `dispose` method of an {@link IDisposable}.
23843
- *
23844
- * A {@link DisposableStore} is also an {@link IDisposable}, which means it can be managed by another {@link DisposableStore}.
23845
- *
23846
- * @example
23847
- * ```ts
23848
- * import { type IDisposable, disposableStore } from "@wopjs/disposable";
23849
- *
23850
- * class A implements IDisposable {
23851
- * dispose = disposableStore()
23852
- * constructor() {
23853
- * this.dispose.add(...);
23854
- * }
23855
- * }
23856
- *
23857
- * class B implements IDisposable {
23858
- * dispose = disposableStore()
23859
- * a = this.dispose.add(new A())
23860
- * constructor() {
23861
- * this.dispose.add(...);
23862
- * }
23863
- * }
23864
- *
23865
- * const b = new B();
23866
- * b.dispose(); // dispose both `b` and `b.a`.
23867
- * ```
23868
- *
23869
- * @param disposables Optional array of {@link DisposableType}s added to the store.
23870
- * @returns A disposable store.
23871
- */
23872
- function disposableStore(disposables) {
23873
- let isDisposing;
23874
- function disposableStore() {
23875
- if (!isDisposing) {
23876
- isDisposing = 1;
23877
- isDisposing = disposableStore._disposables_ = disposableStore._disposables_?.forEach(dispose);
23878
- }
23879
- }
23880
- disposableStore.dispose = disposableStore;
23881
- disposableStore.size = size$3;
23882
- disposableStore.has = has$2;
23883
- disposableStore.add = add$1;
23884
- disposableStore.make = make;
23885
- disposableStore.remove = remove$1;
23886
- disposableStore.flush = flush$1;
23887
- if (disposables) disposableStore.add(disposables);
23888
- return disposableStore;
23889
- }
23890
- function _addOne(disposable) {
23891
- if (!this._disposables_?.has(disposable)) {
23892
- (this._disposables_ ??= /* @__PURE__ */ new Set()).add(disposable);
23893
- if (isAbortable(disposable)) disposable.abortable(remove$1.bind(this, disposable));
23894
- }
23895
- }
23896
- function add$1(disposables) {
23897
- Array.isArray(disposables) ? disposables.forEach(_addOne, this) : _addOne.call(this, disposables);
23898
- return disposables;
23899
- }
23900
- function flush$1(disposable) {
23901
- dispose(disposable ? this.remove(disposable) && disposable : this);
23902
- }
23903
- function has$2(disposable) {
23904
- return !!this._disposables_?.has(disposable);
23905
- }
23906
- function make(executor) {
23907
- const disposable = executor();
23908
- return disposable && this.add(disposable);
23909
- }
23910
- function remove$1(disposable) {
23911
- return !!this._disposables_?.delete(disposable);
23912
- }
23913
- function size$3() {
23914
- return this._disposables_?.size || 0;
23915
- }
23916
- //#endregion
23917
23614
  //#region ../../node_modules/.bun/value-enhancer@5.7.2/node_modules/value-enhancer/dist/index.mjs
23918
- var INIT_VALUE, identity$4, strictEqual, arrayShallowEqual, getValue, getValues, getValVersion, invoke, attachSetter, isVal, tick, pendingTasks1, pendingTasks2, pendingTasks, pending, flush, schedule, cancelTask, registry$1, ValAgent, RefValAgent, ValImpl, readonlyVal, val, from$1, combine$1, compute, derive;
23615
+ var INIT_VALUE, identity$4, strictEqual, arrayShallowEqual, getValue, getValues, getValVersion, invoke, attachSetter, isVal, tick, pendingTasks1, pendingTasks2, pendingTasks, pending, flush$1, schedule, cancelTask, registry$1, ValAgent, RefValAgent, ValImpl, readonlyVal, val, from$1, combine$1, compute, derive;
23919
23616
  var init_dist$3 = __esmMin((() => {
23920
23617
  INIT_VALUE = {};
23921
23618
  identity$4 = (value) => value;
@@ -23944,7 +23641,7 @@ var OpenFlowRenderer = (function(exports) {
23944
23641
  pendingTasks1 = /* @__PURE__ */ new Set();
23945
23642
  pendingTasks2 = /* @__PURE__ */ new Set();
23946
23643
  pendingTasks = pendingTasks1;
23947
- flush = () => {
23644
+ flush$1 = () => {
23948
23645
  const currentPendingTasks = pendingTasks;
23949
23646
  pendingTasks = pendingTasks === pendingTasks1 ? pendingTasks2 : pendingTasks1;
23950
23647
  pending = false;
@@ -23953,7 +23650,7 @@ var OpenFlowRenderer = (function(exports) {
23953
23650
  };
23954
23651
  schedule = (task) => {
23955
23652
  pendingTasks.add(task);
23956
- pending = pending || tick.then(flush);
23653
+ pending = pending || tick.then(flush$1);
23957
23654
  };
23958
23655
  cancelTask = (task) => pendingTasks.delete(task);
23959
23656
  registry$1 = /* @__PURE__ */ new FinalizationRegistry(invoke);
@@ -24268,6 +23965,658 @@ var OpenFlowRenderer = (function(exports) {
24268
23965
  };
24269
23966
  }));
24270
23967
  //#endregion
23968
+ //#region ../../node_modules/.bun/use-value-enhancer@5.0.7+5fffd67310d91248/node_modules/use-value-enhancer/dist/use-value-enhancer.mjs
23969
+ var import_react$3, getVal, noop$3, returnsNoop, defaultArgs, useValWithUseSyncExternalStore, useValWithUseEffect, useVal;
23970
+ var init_use_value_enhancer = __esmMin((() => {
23971
+ import_react$3 = /* @__PURE__ */ __toESM(require_react(), 1);
23972
+ init_dist$3();
23973
+ getVal = ($) => isVal($) ? $ : isVal($ == null ? void 0 : $.$) ? $.$ : void 0;
23974
+ noop$3 = () => {};
23975
+ returnsNoop = () => noop$3;
23976
+ defaultArgs = [returnsNoop, returnsNoop];
23977
+ useValWithUseSyncExternalStore = (v, eager = true) => {
23978
+ const args = (0, import_react$3.useMemo)(() => {
23979
+ const v$2 = getVal(v);
23980
+ return v$2 && [
23981
+ (onChange) => v$2.subscribe(onChange, eager),
23982
+ () => v$2.$version,
23983
+ v$2
23984
+ ];
23985
+ }, [v, eager]);
23986
+ const [subscriber, getSnapshot, v$] = args != null ? args : defaultArgs;
23987
+ const version = import_react$3.useSyncExternalStore(subscriber, getSnapshot, getSnapshot);
23988
+ const value = (0, import_react$3.useMemo)(() => v$ ? v$.get() : v, [
23989
+ version,
23990
+ v$,
23991
+ v
23992
+ ]);
23993
+ (0, import_react$3.useDebugValue)(value);
23994
+ return value;
23995
+ };
23996
+ useValWithUseEffect = (v, eager = true) => {
23997
+ const v$ = (0, import_react$3.useMemo)(() => getVal(v), [v]);
23998
+ const [version, setVersion] = (0, import_react$3.useState)(() => v$ == null ? void 0 : v$.$version);
23999
+ (0, import_react$3.useEffect)(() => {
24000
+ if (v$) {
24001
+ const versionSetter = () => v$.$version;
24002
+ return v$.subscribe(() => setVersion(versionSetter), eager);
24003
+ }
24004
+ }, [v$, eager]);
24005
+ const value = (0, import_react$3.useMemo)(() => v$ ? v$.get() : v, [
24006
+ version,
24007
+ v$,
24008
+ v
24009
+ ]);
24010
+ (0, import_react$3.useDebugValue)(value);
24011
+ return value;
24012
+ };
24013
+ useVal = /* @__PURE__ */ (() => import_react$3.useSyncExternalStore ? useValWithUseSyncExternalStore : useValWithUseEffect)();
24014
+ }));
24015
+ //#endregion
24016
+ //#region src/connector/common/providerIconCache.ts
24017
+ init_use_value_enhancer();
24018
+ var defaultMaxAgeMs = 864e5;
24019
+ var dataUrl = (entry) => `data:${entry.contentType};base64,${entry.body}`;
24020
+ function decodeRecord(value) {
24021
+ if (value == null || typeof value !== "object") return;
24022
+ const v = value;
24023
+ 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;
24024
+ return v;
24025
+ }
24026
+ function encodeBytes(bytes) {
24027
+ let text = "";
24028
+ for (let index = 0; index < bytes.length; index += 8192) text += String.fromCharCode(...bytes.subarray(index, index + 8192));
24029
+ return btoa(text);
24030
+ }
24031
+ function freshness(response, immutable, previous) {
24032
+ const control = response.headers.get("cache-control") ?? "";
24033
+ if (/\bno-cache\b/i.test(control)) return 0;
24034
+ if (immutable) return null;
24035
+ const maxAge = /(?:^|,)\s*max-age\s*=\s*"?(\d+)/i.exec(control);
24036
+ if (maxAge) return Math.max(0, Number(maxAge[1]) * 1e3 - (Number(response.headers.get("age")) || 0) * 1e3);
24037
+ const expires = Date.parse(response.headers.get("expires") ?? "");
24038
+ if (Number.isFinite(expires)) return Math.max(0, expires - Date.parse(response.headers.get("date") ?? (/* @__PURE__ */ new Date()).toUTCString()));
24039
+ return previous?.maxAgeMs ?? defaultMaxAgeMs;
24040
+ }
24041
+ /** Complete image responses in bounded, identity-checked slots; no catalog entities live here. */
24042
+ var ProviderIconCache = class {
24043
+ #memory = /* @__PURE__ */ new Map();
24044
+ #pending = /* @__PURE__ */ new Map();
24045
+ #targets = /* @__PURE__ */ new Map();
24046
+ #writes = /* @__PURE__ */ new Map();
24047
+ constructor(options) {
24048
+ this.options = options;
24049
+ if (!options.scope.trim()) throw new TypeError("Provider icon cache scope must be nonempty.");
24050
+ }
24051
+ get(request, options = {}) {
24052
+ if (request.url.startsWith("data:image/")) return Promise.resolve(request.url);
24053
+ let protocol;
24054
+ try {
24055
+ protocol = new URL(request.url).protocol;
24056
+ } catch (error) {
24057
+ return Promise.reject(error);
24058
+ }
24059
+ if (!["http:", "https:"].includes(protocol)) return Promise.reject(/* @__PURE__ */ new TypeError("Unsupported Provider icon URL."));
24060
+ const slot = JSON.stringify([
24061
+ "open-flow:provider-icons",
24062
+ 1,
24063
+ this.options.scope,
24064
+ request.kind,
24065
+ request.kind === "sprite" ? request.theme : request.providerId
24066
+ ]);
24067
+ const version = request.kind === "sprite" ? request.version : null;
24068
+ const identity = JSON.stringify([request.url, version]);
24069
+ const offline = options.allowNetwork === false || this.options.mode === "offline";
24070
+ const key = JSON.stringify([
24071
+ slot,
24072
+ identity,
24073
+ offline
24074
+ ]);
24075
+ const pending = this.#pending.get(key);
24076
+ if (pending) return pending;
24077
+ if (!offline) this.#targets.set(slot, identity);
24078
+ const promise = this.#load(slot, identity, request.url, version, offline).finally(() => this.#pending.delete(key));
24079
+ this.#pending.set(key, promise);
24080
+ return promise;
24081
+ }
24082
+ async #read(slot, url, version) {
24083
+ const memory = this.#memory.get(slot);
24084
+ if (this.#memory.has(slot) && (!memory || memory.sourceUrl === url && memory.spriteVersion === version)) return memory;
24085
+ if (!this.options.delegate) return this.#memory.get(slot);
24086
+ try {
24087
+ const stored = await this.options.delegate.get(slot);
24088
+ if (stored === void 0) return this.#memory.get(slot);
24089
+ const entry = decodeRecord(stored);
24090
+ if (entry) {
24091
+ this.#memory.set(slot, entry);
24092
+ return entry;
24093
+ }
24094
+ this.#memory.delete(slot);
24095
+ await this.options.delegate.delete(slot);
24096
+ } catch {
24097
+ return this.#memory.get(slot);
24098
+ }
24099
+ }
24100
+ async #store(slot, identity, entry) {
24101
+ const operation = (this.#writes.get(slot) ?? Promise.resolve()).then(async () => {
24102
+ if (this.#targets.get(slot) !== identity) return;
24103
+ this.#memory.set(slot, entry);
24104
+ if (!this.options.delegate) return;
24105
+ try {
24106
+ if (entry) await this.options.delegate.set(slot, { ...entry });
24107
+ else await this.options.delegate.delete(slot);
24108
+ } catch {}
24109
+ });
24110
+ this.#writes.set(slot, operation);
24111
+ try {
24112
+ await operation;
24113
+ } finally {
24114
+ if (this.#writes.get(slot) === operation) this.#writes.delete(slot);
24115
+ }
24116
+ }
24117
+ async #load(slot, identity, url, version, offline) {
24118
+ const stored = await this.#read(slot, url, version);
24119
+ const cached = stored?.sourceUrl === url && stored.spriteVersion === version ? stored : void 0;
24120
+ const age = cached == null ? Infinity : Date.now() - cached.validatedAt;
24121
+ if (cached && (offline || this.options.mode !== "refresh" && age >= 0 && (cached.maxAgeMs === null || age < cached.maxAgeMs))) return dataUrl(cached);
24122
+ if (offline) throw new Error(`Provider icon is not cached: ${url}`);
24123
+ const response = await (this.options.fetch ?? globalThis.fetch)(url, {
24124
+ credentials: "omit",
24125
+ referrerPolicy: "no-referrer",
24126
+ signal: AbortSignal.timeout(15e3),
24127
+ headers: cached?.etag ? { "if-none-match": cached.etag } : {}
24128
+ });
24129
+ if (response.status !== 304 && !response.ok) throw new Error(`Could not load Provider icon: ${response.status}`);
24130
+ if (response.status === 304 && !cached) throw new Error("Provider icon returned 304 without a cached image.");
24131
+ const contentType = response.status === 304 ? cached.contentType : response.headers.get("content-type")?.split(";")[0]?.trim().toLowerCase();
24132
+ if (!contentType || !/^image\/[\w.+-]+$/i.test(contentType)) throw new Error("Provider icon response is not an image.");
24133
+ const body = response.status === 304 ? cached.body : encodeBytes(new Uint8Array(await response.arrayBuffer()));
24134
+ if (!body) throw new Error("Provider icon response is empty.");
24135
+ const entry = {
24136
+ formatVersion: 1,
24137
+ sourceUrl: url,
24138
+ spriteVersion: version,
24139
+ contentType,
24140
+ body,
24141
+ etag: response.headers.get("etag") ?? (response.status === 304 ? cached.etag : null),
24142
+ validatedAt: Date.now(),
24143
+ maxAgeMs: freshness(response, version !== null, response.status === 304 ? cached : void 0)
24144
+ };
24145
+ await this.#store(slot, identity, /\bno-store\b/i.test(response.headers.get("cache-control") ?? "") ? void 0 : entry);
24146
+ return dataUrl(entry);
24147
+ }
24148
+ };
24149
+ //#endregion
24150
+ //#region src/ui/browser/icons/providerIconResource.ts
24151
+ init_dist$3();
24152
+ var ProviderIconCacheContext = (0, import_react$4.createContext)(void 0);
24153
+ /** IDB holds the same opaque JSON records as a host's disk delegate. */
24154
+ function indexedDbIconDelegate() {
24155
+ let database;
24156
+ function open() {
24157
+ database ??= new Promise((resolve, reject) => {
24158
+ const request = indexedDB.open("open-flow-provider-icons", 1);
24159
+ request.addEventListener("upgradeneeded", () => request.result.createObjectStore("icons"), { once: true });
24160
+ request.addEventListener("error", () => reject(request.error), { once: true });
24161
+ request.addEventListener("blocked", () => reject(/* @__PURE__ */ new Error("Provider icon cache is blocked.")), { once: true });
24162
+ request.addEventListener("success", () => {
24163
+ const db = request.result;
24164
+ db.addEventListener("versionchange", () => {
24165
+ db.close();
24166
+ database = void 0;
24167
+ }, { once: true });
24168
+ resolve(db);
24169
+ }, { once: true });
24170
+ }).catch((error) => {
24171
+ database = void 0;
24172
+ throw error;
24173
+ });
24174
+ return database;
24175
+ }
24176
+ async function transaction(mode, operation) {
24177
+ const db = await open();
24178
+ return new Promise((resolve, reject) => {
24179
+ const tx = db.transaction("icons", mode);
24180
+ const request = operation(tx.objectStore("icons"));
24181
+ tx.addEventListener("complete", () => resolve(request.result), { once: true });
24182
+ tx.addEventListener("abort", () => reject(tx.error ?? request.error), { once: true });
24183
+ tx.addEventListener("error", () => reject(tx.error ?? request.error), { once: true });
24184
+ });
24185
+ }
24186
+ return {
24187
+ get: (key) => transaction("readonly", (store) => store.get(key)),
24188
+ set: async (key, value) => {
24189
+ await transaction("readwrite", (store) => store.put(value, key));
24190
+ },
24191
+ delete: async (key) => {
24192
+ await transaction("readwrite", (store) => store.delete(key));
24193
+ }
24194
+ };
24195
+ }
24196
+ var browserCache;
24197
+ function defaultBrowserIconCache() {
24198
+ return browserCache ??= new ProviderIconCache({
24199
+ scope: "browser",
24200
+ delegate: indexedDbIconDelegate()
24201
+ });
24202
+ }
24203
+ function useProviderIconCache() {
24204
+ return (0, import_react$4.useContext)(ProviderIconCacheContext) ?? defaultBrowserIconCache();
24205
+ }
24206
+ var loading = { status: "loading" };
24207
+ function createIconResource(cache, request, ready) {
24208
+ const state = val(ready ?? loading);
24209
+ let pending;
24210
+ return {
24211
+ state,
24212
+ refresh() {
24213
+ if (pending) return pending;
24214
+ const previous = state.value.status === "loaded" ? state.value : void 0;
24215
+ if (previous) state.set({
24216
+ ...previous,
24217
+ refreshing: true
24218
+ });
24219
+ else if (state.value.status === "failed") state.set(loading);
24220
+ pending = (async () => {
24221
+ let image;
24222
+ try {
24223
+ const url = await cache.get(request);
24224
+ if (previous?.url === url) {
24225
+ state.set({
24226
+ ...previous,
24227
+ refreshing: false
24228
+ });
24229
+ return;
24230
+ }
24231
+ image = new Image();
24232
+ image.src = url;
24233
+ await image.decode();
24234
+ state.set({
24235
+ status: "loaded",
24236
+ url,
24237
+ image
24238
+ });
24239
+ } catch {
24240
+ if (image) image.src = "";
24241
+ state.set(previous ? {
24242
+ ...previous,
24243
+ refreshing: false
24244
+ } : { status: "failed" });
24245
+ }
24246
+ })().finally(() => {
24247
+ pending = void 0;
24248
+ });
24249
+ return pending;
24250
+ }
24251
+ };
24252
+ }
24253
+ var resources$1 = /* @__PURE__ */ new WeakMap();
24254
+ /** Components read ready state synchronously; only the shared owner fetches and decodes. */
24255
+ function useProviderIconResource(request, crop) {
24256
+ const cache = useProviderIconCache();
24257
+ const slot = JSON.stringify([request.kind, request.kind === "sprite" ? request.theme : request.providerId]);
24258
+ const identity = JSON.stringify([
24259
+ slot,
24260
+ request.url,
24261
+ request.kind === "sprite" ? request.version : null
24262
+ ]);
24263
+ const previous = (0, import_react$4.useRef)();
24264
+ const resource = (0, import_react$4.useMemo)(() => {
24265
+ let slots = resources$1.get(cache);
24266
+ if (!slots) {
24267
+ slots = /* @__PURE__ */ new Map();
24268
+ resources$1.set(cache, slots);
24269
+ }
24270
+ let current = slots.get(slot);
24271
+ if (current?.identity !== identity) {
24272
+ const value = previous.current?.identity === identity ? previous.current.resource.state.value : void 0;
24273
+ current = {
24274
+ identity,
24275
+ resource: createIconResource(cache, request, value?.status === "loaded" ? value : void 0)
24276
+ };
24277
+ slots.set(slot, current);
24278
+ }
24279
+ previous.current = current;
24280
+ return current.resource;
24281
+ }, [cache, identity]);
24282
+ const state = useVal(resource.state);
24283
+ (0, import_react$4.useEffect)(() => {
24284
+ resource.refresh();
24285
+ }, [resource]);
24286
+ return (0, import_react$4.useMemo)(() => {
24287
+ if (state.status !== "loaded" || !crop) return state;
24288
+ const canvas = document.createElement("canvas");
24289
+ try {
24290
+ canvas.width = canvas.height = crop.size;
24291
+ const context = canvas.getContext("2d");
24292
+ if (!context) throw new Error("Could not crop the Provider icon.");
24293
+ context.drawImage(state.image, crop.x, crop.y, crop.size, crop.size, 0, 0, crop.size, crop.size);
24294
+ return {
24295
+ ...state,
24296
+ url: canvas.toDataURL("image/png")
24297
+ };
24298
+ } catch {
24299
+ return { status: "failed" };
24300
+ } finally {
24301
+ canvas.width = canvas.height = 0;
24302
+ }
24303
+ }, [
24304
+ state,
24305
+ crop?.x,
24306
+ crop?.y,
24307
+ crop?.size
24308
+ ]);
24309
+ }
24310
+ //#endregion
24311
+ //#region src/ui/browser/icons/ContentIcon.tsx
24312
+ /** Standalone image capture crops sprites and uses cross-origin-readable images. */
24313
+ var IconImageCrossOriginContext = (0, import_react$4.createContext)(void 0);
24314
+ /** A bundled, theme-aware placeholder that does not load a remote icon. */
24315
+ var placeholderIcon = "data:application/vnd.open-flow.placeholder-icon,";
24316
+ var ContentIcon = ({ src, className, fallback = null, loading = "lazy", decoding = "async" }) => {
24317
+ const crossOrigin = (0, import_react$4.useContext)(IconImageCrossOriginContext);
24318
+ const sprite = (0, import_react$4.useMemo)(() => parseSpriteIcon(src), [src]);
24319
+ const image = (0, import_react$4.useMemo)(() => parseImageIcon(src), [src]);
24320
+ const source = image?.source ?? src;
24321
+ const result = (0, import_react$4.useMemo)(() => parseIconifyIcon(source), [source]);
24322
+ const [error, setError] = (0, import_react$4.useState)();
24323
+ const onError = () => setError(source);
24324
+ if (sprite) return /* @__PURE__ */ (0, import_jsx_runtime$2.jsx)(SpriteIcon, {
24325
+ className,
24326
+ fallback,
24327
+ loading,
24328
+ decoding,
24329
+ sprite
24330
+ });
24331
+ if (image?.providerId) return /* @__PURE__ */ (0, import_jsx_runtime$2.jsx)(ProviderImage, {
24332
+ className,
24333
+ fallback,
24334
+ loading,
24335
+ decoding,
24336
+ image
24337
+ });
24338
+ if (source === "data:application/vnd.open-flow.placeholder-icon,") return /* @__PURE__ */ (0, import_jsx_runtime$2.jsx)("i", {
24339
+ "aria-hidden": "true",
24340
+ className: clsx("i-lucide-light:plug", className)
24341
+ });
24342
+ if (source?.startsWith(initialsIconPrefix)) {
24343
+ if (crossOrigin && fallback != null) return /* @__PURE__ */ (0, import_jsx_runtime$2.jsx)(import_jsx_runtime$2.Fragment, { children: fallback });
24344
+ return /* @__PURE__ */ (0, import_jsx_runtime$2.jsx)("span", {
24345
+ "data-icon-kind": "initials",
24346
+ "aria-hidden": "true",
24347
+ className: clsx(ContentIcon_module_default.initials, className),
24348
+ children: /* @__PURE__ */ (0, import_jsx_runtime$2.jsx)("span", { children: source.slice(initialsIconPrefix.length) })
24349
+ });
24350
+ }
24351
+ if (!source) return fallback;
24352
+ if (source === error && crossOrigin && fallback != null) return /* @__PURE__ */ (0, import_jsx_runtime$2.jsx)(import_jsx_runtime$2.Fragment, { children: fallback });
24353
+ if (source === error) return image == null ? fallback : /* @__PURE__ */ (0, import_jsx_runtime$2.jsx)(ContentIcon, {
24354
+ className,
24355
+ fallback,
24356
+ src: image.fallback,
24357
+ loading,
24358
+ decoding
24359
+ });
24360
+ return result ? /* @__PURE__ */ (0, import_jsx_runtime$2.jsx)(IconifyIcon, {
24361
+ collection: result.collection,
24362
+ icon: result.icon,
24363
+ color: result.color,
24364
+ className,
24365
+ onError
24366
+ }) : /* @__PURE__ */ (0, import_jsx_runtime$2.jsx)("img", {
24367
+ className: clsx(ContentIcon_module_default.img, className),
24368
+ src: source,
24369
+ alt: "",
24370
+ crossOrigin,
24371
+ decoding,
24372
+ loading,
24373
+ referrerPolicy: "no-referrer",
24374
+ onError
24375
+ });
24376
+ };
24377
+ var initialsIconPrefix = "data:application/vnd.open-flow.initials,";
24378
+ var imageIconPrefix = "data:application/vnd.open-flow.image-icon+json,";
24379
+ function imageIcon(source, fallback, providerId) {
24380
+ return `${imageIconPrefix}${encodeURIComponent(JSON.stringify({
24381
+ fallback,
24382
+ source,
24383
+ ...providerId == null ? {} : { providerId }
24384
+ }))}`;
24385
+ }
24386
+ function parseImageIcon(src) {
24387
+ if (!src?.startsWith(imageIconPrefix)) return;
24388
+ try {
24389
+ const value = JSON.parse(decodeURIComponent(src.slice(47)));
24390
+ if (typeof value.fallback == "string" && typeof value.source == "string") return {
24391
+ fallback: value.fallback,
24392
+ source: value.source,
24393
+ ...typeof value.providerId === "string" ? { providerId: value.providerId } : {}
24394
+ };
24395
+ } catch {
24396
+ return;
24397
+ }
24398
+ }
24399
+ function parseIconifyIcon(src) {
24400
+ if (src && src.length > 2 && src[0] === ":" && src.endsWith(":")) {
24401
+ const [, collection, icon, color] = src.split(":");
24402
+ if (collection && icon) return {
24403
+ collection,
24404
+ icon,
24405
+ color: color || "currentColor"
24406
+ };
24407
+ }
24408
+ return null;
24409
+ }
24410
+ var spriteIconPrefix = "data:application/vnd.open-flow.sprite-icon+json,";
24411
+ function spriteIcon(appearance, fallback) {
24412
+ return `${spriteIconPrefix}${encodeURIComponent(JSON.stringify({
24413
+ ...appearance,
24414
+ fallback
24415
+ }))}`;
24416
+ }
24417
+ function parseSpriteIcon(src) {
24418
+ if (!src?.startsWith(spriteIconPrefix)) return;
24419
+ try {
24420
+ const value = JSON.parse(decodeURIComponent(src.slice(48)));
24421
+ const appearance = providerIconAppearance(value?.iconSprite, value?.iconSpritePosition);
24422
+ if (appearance.iconSprite && appearance.iconSpritePosition && typeof value.fallback == "string") return {
24423
+ iconSprite: appearance.iconSprite,
24424
+ iconSpritePosition: appearance.iconSpritePosition,
24425
+ fallback: value.fallback
24426
+ };
24427
+ } catch {
24428
+ return;
24429
+ }
24430
+ }
24431
+ function SpriteIcon({ sprite, ...props }) {
24432
+ const theme = (0, import_react$4.useContext)(IconThemeContext);
24433
+ const capture = (0, import_react$4.useContext)(IconImageCrossOriginContext) != null;
24434
+ const { iconSprite: m, iconSpritePosition: p } = sprite;
24435
+ const resource = useProviderIconResource({
24436
+ kind: "sprite",
24437
+ theme,
24438
+ url: theme == "dark" ? m.darkUrl : m.lightUrl,
24439
+ version: m.version
24440
+ }, capture ? {
24441
+ x: p.x,
24442
+ y: p.y,
24443
+ size: m.iconSize
24444
+ } : void 0);
24445
+ if (resource.status == "failed") return /* @__PURE__ */ (0, import_jsx_runtime$2.jsx)(ContentIcon, {
24446
+ ...props,
24447
+ src: sprite.fallback
24448
+ });
24449
+ if (resource.status === "loading") return /* @__PURE__ */ (0, import_jsx_runtime$2.jsx)(PendingIcon, {
24450
+ className: props.className,
24451
+ fallback: props.fallback
24452
+ });
24453
+ if (capture) return /* @__PURE__ */ (0, import_jsx_runtime$2.jsx)("img", {
24454
+ alt: "",
24455
+ className: clsx(ContentIcon_module_default.img, props.className),
24456
+ "data-render-pending": resource.refreshing || void 0,
24457
+ src: resource.url,
24458
+ decoding: "sync"
24459
+ });
24460
+ return /* @__PURE__ */ (0, import_jsx_runtime$2.jsx)("span", {
24461
+ "aria-hidden": "true",
24462
+ "data-render-pending": resource.refreshing || void 0,
24463
+ className: clsx(ContentIcon_module_default.sprite, props.className),
24464
+ children: /* @__PURE__ */ (0, import_jsx_runtime$2.jsx)("span", { style: {
24465
+ backgroundImage: `url(${JSON.stringify(resource.url)})`,
24466
+ width: `${m.width / m.iconSize * 100}%`,
24467
+ height: `${m.height / m.iconSize * 100}%`,
24468
+ left: `${-p.x / m.iconSize * 100}%`,
24469
+ top: `${-p.y / m.iconSize * 100}%`
24470
+ } })
24471
+ });
24472
+ }
24473
+ function ProviderImage({ image, ...props }) {
24474
+ const resource = useProviderIconResource({
24475
+ kind: "image",
24476
+ providerId: image.providerId,
24477
+ url: image.source
24478
+ });
24479
+ if (resource.status === "failed") return /* @__PURE__ */ (0, import_jsx_runtime$2.jsx)(ContentIcon, {
24480
+ ...props,
24481
+ src: image.fallback
24482
+ });
24483
+ if (resource.status === "loading") return /* @__PURE__ */ (0, import_jsx_runtime$2.jsx)(PendingIcon, {
24484
+ className: props.className,
24485
+ fallback: props.fallback
24486
+ });
24487
+ return /* @__PURE__ */ (0, import_jsx_runtime$2.jsx)("img", {
24488
+ alt: "",
24489
+ className: clsx(ContentIcon_module_default.img, props.className),
24490
+ "data-render-pending": resource.refreshing || void 0,
24491
+ src: resource.url,
24492
+ loading: props.loading,
24493
+ decoding: props.decoding
24494
+ });
24495
+ }
24496
+ function PendingIcon({ className, fallback }) {
24497
+ return /* @__PURE__ */ (0, import_jsx_runtime$2.jsx)("span", {
24498
+ "aria-hidden": "true",
24499
+ className: clsx(ContentIcon_module_default.pending, className),
24500
+ "data-render-pending": true,
24501
+ children: fallback ?? /* @__PURE__ */ (0, import_jsx_runtime$2.jsx)(ContentIcon, {
24502
+ src: "data:application/vnd.open-flow.placeholder-icon,",
24503
+ className
24504
+ })
24505
+ });
24506
+ }
24507
+ //#endregion
24508
+ //#region ../../assets/logo/open-flow-dark.svg
24509
+ var open_flow_dark_default = "data:image/svg+xml,%3csvg%20xmlns='http://www.w3.org/2000/svg'%20width='100'%20height='100'%20viewBox='0%200%20100%20100'%20role='img'%20aria-label='Open%20Flow'%3e%3cpath%20fill='%23e0e2e6'%20d='M32%2016H68Q84%2016%2084%2032V36H68C46%2036%2054%2056%2032%2056H16V32Q16%2016%2032%2016Z'/%3e%3cpath%20fill='%238c919a'%20d='M16%2068H32C54%2068%2046%2048%2068%2048H84V68Q84%2084%2068%2084H32Q16%2084%2016%2068Z'/%3e%3c/svg%3e";
24510
+ //#endregion
24511
+ //#region ../../assets/logo/open-flow-light.svg
24512
+ var open_flow_light_default = "data:image/svg+xml,%3csvg%20xmlns='http://www.w3.org/2000/svg'%20width='100'%20height='100'%20viewBox='0%200%20100%20100'%20role='img'%20aria-label='Open%20Flow'%3e%3cpath%20fill='%2344474c'%20d='M32%2016H68Q84%2016%2084%2032V36H68C46%2036%2054%2056%2032%2056H16V32Q16%2016%2032%2016Z'/%3e%3cpath%20fill='%2393979f'%20d='M16%2068H32C54%2068%2046%2048%2068%2048H84V68Q84%2084%2068%2084H32Q16%2084%2016%2068Z'/%3e%3c/svg%3e";
24513
+ //#endregion
24514
+ //#region src/ui/browser/logo.tsx
24515
+ function openFlowLogoSource(theme) {
24516
+ return theme === "dark" ? open_flow_dark_default : open_flow_light_default;
24517
+ }
24518
+ //#endregion
24519
+ //#region ../../node_modules/.bun/@wopjs+disposable@0.1.24/node_modules/@wopjs/disposable/dist/index.mjs
24520
+ var isFn = (value) => !!(value && value.constructor && value.call && value.apply);
24521
+ /**
24522
+ * Check if a value is a {@link DisposableType}.
24523
+ * @param value The value to check.
24524
+ * @returns True if the value is a {@link DisposableType}, false otherwise.
24525
+ */
24526
+ var isDisposable = (value) => isFn(value) || isFn(value?.dispose);
24527
+ /**
24528
+ * Dispose a disposable object or a disposer function. Log the error if any.
24529
+ * @param disposable A disposable object or a disposer function. Do nothing otherwise.
24530
+ */
24531
+ function dispose(disposable) {
24532
+ try {
24533
+ if (disposable) {
24534
+ if (isFn(disposable.dispose)) disposable.dispose();
24535
+ else if (isFn(disposable)) disposable();
24536
+ }
24537
+ } catch (e) {
24538
+ console.error(e);
24539
+ }
24540
+ }
24541
+ var isAbortable = (disposable) => isDisposable(disposable) && isFn(disposable.abortable);
24542
+ /**
24543
+ * Create a {@link DisposableStore} that manages {@link Disposer}s and {@link IDisposable}s.
24544
+ *
24545
+ * A {@link DisposableStore} is also a {@link Disposer}, which means it can be the `dispose` method of an {@link IDisposable}.
24546
+ *
24547
+ * A {@link DisposableStore} is also an {@link IDisposable}, which means it can be managed by another {@link DisposableStore}.
24548
+ *
24549
+ * @example
24550
+ * ```ts
24551
+ * import { type IDisposable, disposableStore } from "@wopjs/disposable";
24552
+ *
24553
+ * class A implements IDisposable {
24554
+ * dispose = disposableStore()
24555
+ * constructor() {
24556
+ * this.dispose.add(...);
24557
+ * }
24558
+ * }
24559
+ *
24560
+ * class B implements IDisposable {
24561
+ * dispose = disposableStore()
24562
+ * a = this.dispose.add(new A())
24563
+ * constructor() {
24564
+ * this.dispose.add(...);
24565
+ * }
24566
+ * }
24567
+ *
24568
+ * const b = new B();
24569
+ * b.dispose(); // dispose both `b` and `b.a`.
24570
+ * ```
24571
+ *
24572
+ * @param disposables Optional array of {@link DisposableType}s added to the store.
24573
+ * @returns A disposable store.
24574
+ */
24575
+ function disposableStore(disposables) {
24576
+ let isDisposing;
24577
+ function disposableStore() {
24578
+ if (!isDisposing) {
24579
+ isDisposing = 1;
24580
+ isDisposing = disposableStore._disposables_ = disposableStore._disposables_?.forEach(dispose);
24581
+ }
24582
+ }
24583
+ disposableStore.dispose = disposableStore;
24584
+ disposableStore.size = size$3;
24585
+ disposableStore.has = has$2;
24586
+ disposableStore.add = add$1;
24587
+ disposableStore.make = make;
24588
+ disposableStore.remove = remove$1;
24589
+ disposableStore.flush = flush;
24590
+ if (disposables) disposableStore.add(disposables);
24591
+ return disposableStore;
24592
+ }
24593
+ function _addOne(disposable) {
24594
+ if (!this._disposables_?.has(disposable)) {
24595
+ (this._disposables_ ??= /* @__PURE__ */ new Set()).add(disposable);
24596
+ if (isAbortable(disposable)) disposable.abortable(remove$1.bind(this, disposable));
24597
+ }
24598
+ }
24599
+ function add$1(disposables) {
24600
+ Array.isArray(disposables) ? disposables.forEach(_addOne, this) : _addOne.call(this, disposables);
24601
+ return disposables;
24602
+ }
24603
+ function flush(disposable) {
24604
+ dispose(disposable ? this.remove(disposable) && disposable : this);
24605
+ }
24606
+ function has$2(disposable) {
24607
+ return !!this._disposables_?.has(disposable);
24608
+ }
24609
+ function make(executor) {
24610
+ const disposable = executor();
24611
+ return disposable && this.add(disposable);
24612
+ }
24613
+ function remove$1(disposable) {
24614
+ return !!this._disposables_?.delete(disposable);
24615
+ }
24616
+ function size$3() {
24617
+ return this._disposables_?.size || 0;
24618
+ }
24619
+ //#endregion
24271
24620
  //#region ../../node_modules/.bun/value-enhancer@5.7.2/node_modules/value-enhancer/dist/collections.mjs
24272
24621
  init_dist$3();
24273
24622
  var ReactiveMapImpl = class extends Map {
@@ -33666,56 +34015,7 @@ var OpenFlowRenderer = (function(exports) {
33666
34015
  return [...properties].toSorted();
33667
34016
  }
33668
34017
  //#endregion
33669
- //#region ../../node_modules/.bun/use-value-enhancer@5.0.7+5fffd67310d91248/node_modules/use-value-enhancer/dist/use-value-enhancer.mjs
33670
- var import_react$3, getVal, noop$3, returnsNoop, defaultArgs, useValWithUseSyncExternalStore, useValWithUseEffect, useVal;
33671
- var init_use_value_enhancer = __esmMin((() => {
33672
- import_react$3 = /* @__PURE__ */ __toESM(require_react(), 1);
33673
- init_dist$3();
33674
- getVal = ($) => isVal($) ? $ : isVal($ == null ? void 0 : $.$) ? $.$ : void 0;
33675
- noop$3 = () => {};
33676
- returnsNoop = () => noop$3;
33677
- defaultArgs = [returnsNoop, returnsNoop];
33678
- useValWithUseSyncExternalStore = (v, eager = true) => {
33679
- const args = (0, import_react$3.useMemo)(() => {
33680
- const v$2 = getVal(v);
33681
- return v$2 && [
33682
- (onChange) => v$2.subscribe(onChange, eager),
33683
- () => v$2.$version,
33684
- v$2
33685
- ];
33686
- }, [v, eager]);
33687
- const [subscriber, getSnapshot, v$] = args != null ? args : defaultArgs;
33688
- const version = import_react$3.useSyncExternalStore(subscriber, getSnapshot, getSnapshot);
33689
- const value = (0, import_react$3.useMemo)(() => v$ ? v$.get() : v, [
33690
- version,
33691
- v$,
33692
- v
33693
- ]);
33694
- (0, import_react$3.useDebugValue)(value);
33695
- return value;
33696
- };
33697
- useValWithUseEffect = (v, eager = true) => {
33698
- const v$ = (0, import_react$3.useMemo)(() => getVal(v), [v]);
33699
- const [version, setVersion] = (0, import_react$3.useState)(() => v$ == null ? void 0 : v$.$version);
33700
- (0, import_react$3.useEffect)(() => {
33701
- if (v$) {
33702
- const versionSetter = () => v$.$version;
33703
- return v$.subscribe(() => setVersion(versionSetter), eager);
33704
- }
33705
- }, [v$, eager]);
33706
- const value = (0, import_react$3.useMemo)(() => v$ ? v$.get() : v, [
33707
- version,
33708
- v$,
33709
- v
33710
- ]);
33711
- (0, import_react$3.useDebugValue)(value);
33712
- return value;
33713
- };
33714
- useVal = /* @__PURE__ */ (() => import_react$3.useSyncExternalStore ? useValWithUseSyncExternalStore : useValWithUseEffect)();
33715
- }));
33716
- //#endregion
33717
34018
  //#region src/canvas/browser/components/minimap.tsx
33718
- init_use_value_enhancer();
33719
34019
  var NodeMiniMapContext = /*#__PURE__*/ (0, import_react$4.createContext)(NodeMiniMapPhase.None);
33720
34020
  var NodeMiniMapProvider = /*#__PURE__*/ (() => NodeMiniMapContext.Provider)();
33721
34021
  function useNodeMiniMapPhase() {
@@ -56607,6 +56907,7 @@ var OpenFlowRenderer = (function(exports) {
56607
56907
  }
56608
56908
  //#endregion
56609
56909
  //#region src/canvas/browser/graph/Edges/BasicEdge.tsx
56910
+ init_use_value_enhancer();
56610
56911
  function BasicEdge(props) {
56611
56912
  const arrowId = (0, import_react$4.useId)().replaceAll(":", "");
56612
56913
  const edgeStore = props.data?.store;
@@ -250389,7 +250690,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
250389
250690
  });
250390
250691
  store.reconcile(snapshot, false, language, [], options.ignoredNodeIds ?? []);
250391
250692
  try {
250392
- root.render((0, import_react$4.createElement)(IconifyProvider, null, (0, import_react$4.createElement)(IconImageCrossOriginContext.Provider, { value: "anonymous" }, (0, import_react$4.createElement)(FlowCanvas, {
250693
+ root.render((0, import_react$4.createElement)(ProviderIconCacheContext.Provider, { value: options.iconCache }, (0, import_react$4.createElement)(IconifyProvider, null, (0, import_react$4.createElement)(IconImageCrossOriginContext.Provider, { value: "anonymous" }, (0, import_react$4.createElement)(FlowCanvas, {
250393
250694
  flowCanvasStore: store,
250394
250695
  dark: options.dark ?? false,
250395
250696
  fitView: false,
@@ -250398,7 +250699,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
250398
250699
  onInit: (value) => {
250399
250700
  instance = value;
250400
250701
  }
250401
- }))));
250702
+ })))));
250402
250703
  const deadline = performance.now() + 15e3;
250403
250704
  await waitFor(() => store.$.initialized.value && store.$.rfNodes.value.every((node) => !!node.measured?.width && !!node.measured.height), deadline);
250404
250705
  let hasImagePlaceholders = await prepareImages(host, deadline);
@@ -265686,7 +265987,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
265686
265987
  //#region src/workbench/browser/runtime/providerIcon.ts
265687
265988
  function providerIcon(provider) {
265688
265989
  const source = provider.icon?.trim();
265689
- const original = source ? imageIcon(source, placeholderIcon) : placeholderIcon;
265990
+ const original = source ? imageIcon(source, placeholderIcon, provider.serviceId) : placeholderIcon;
265690
265991
  const appearance = providerIconAppearance(provider.iconSprite, provider.iconSpritePosition);
265691
265992
  return appearance?.iconSprite && appearance.iconSpritePosition ? spriteIcon({
265692
265993
  iconSprite: appearance.iconSprite,
@@ -267722,19 +268023,20 @@ export function identity(value) { return value }
267722
268023
  //#endregion
267723
268024
  //#region src/render/browser/runtime.ts
267724
268025
  /** Runs only inside the caller's Chromium, using the same renderer as Workbench. */
267725
- async function render({ workflow, options }) {
268026
+ async function render({ workflow, options, providers }) {
267726
268027
  const language = options.language ?? "en";
267727
268028
  document.documentElement.lang = language;
267728
268029
  document.body.className = "open-flow-theme open-flow-workbench";
267729
268030
  document.body.dataset.theme = options.dark ? "dark" : "light";
267730
268031
  const i18n = createI18n(language);
267731
268032
  try {
267732
- const result = await flowToPng(designerGraph(workflow, workflow.presentation, [], {}, {}, i18n.t), language, {
268033
+ const result = await flowToPng(designerGraph(workflow, workflow.presentation, [], {}, {}, i18n.t, void 0, [], Object.fromEntries((providers ?? []).map((provider) => [provider.serviceId, provider]))), language, {
267733
268034
  layout: options.layout,
267734
268035
  aspectRatio: options.aspectRatio,
267735
268036
  dark: options.dark,
267736
268037
  frame: options.frame,
267737
- title: options.title ?? workflow.name ?? "Workflow"
268038
+ title: options.title ?? workflow.name ?? "Workflow",
268039
+ iconCache: { get: (request) => globalThis.OpenFlowProviderIcon(request) }
267738
268040
  });
267739
268041
  return {
267740
268042
  dataUrl: await new Promise((resolve, reject) => {