@ixo/editor 5.19.1 → 5.20.0-experimental.2
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/dist/{chunk-HDQKWNUR.mjs → chunk-5U32TIJW.mjs} +2518 -5178
- package/dist/chunk-5U32TIJW.mjs.map +1 -0
- package/dist/chunk-OK2W66I7.mjs +1 -0
- package/dist/chunk-OK2W66I7.mjs.map +1 -0
- package/dist/{chunk-67477PYU.mjs → chunk-OK3ILV2C.mjs} +1269 -218
- package/dist/chunk-OK3ILV2C.mjs.map +1 -0
- package/dist/core/index.d.ts +57 -45
- package/dist/core/index.mjs +3 -4
- package/dist/core/index.mjs.map +1 -1
- package/dist/{graphql-client-xxQMIQzo.d.ts → graphql-client-DGtC9Ajk.d.ts} +1 -1
- package/dist/{index-BoRWeiDg.d.ts → index-gDm2GWBG.d.ts} +132 -10
- package/dist/index.d.ts +3 -3
- package/dist/index.mjs +3 -3
- package/dist/index.mjs.map +1 -1
- package/dist/mantine/index.d.ts +3 -3
- package/dist/mantine/index.mjs +2 -2
- package/dist/{store-DZobLMG3.d.ts → store-B5l8ciUz.d.ts} +76 -67
- package/package.json +1 -1
- package/dist/chunk-67477PYU.mjs.map +0 -1
- package/dist/chunk-HDQKWNUR.mjs.map +0 -1
- package/dist/chunk-K4YAG7AQ.mjs +0 -63
- package/dist/chunk-K4YAG7AQ.mjs.map +0 -1
|
@@ -571,15 +571,68 @@ registerAction({
|
|
|
571
571
|
});
|
|
572
572
|
|
|
573
573
|
// src/core/lib/actionRegistry/actions/pod/listDomainFlows.ts
|
|
574
|
+
function normalizeSelectedTemplates(value) {
|
|
575
|
+
if (!Array.isArray(value)) return [];
|
|
576
|
+
return value.map((item) => {
|
|
577
|
+
if (!item || typeof item !== "object") return null;
|
|
578
|
+
const raw = item;
|
|
579
|
+
const protocolDid = String(raw.protocolDid || "").trim();
|
|
580
|
+
const sourceRoomId = String(raw.sourceRoomId || "").trim();
|
|
581
|
+
if (!protocolDid || !sourceRoomId) return null;
|
|
582
|
+
const sourceLabel = String(raw.sourceLabel || raw.label || sourceRoomId).trim();
|
|
583
|
+
return {
|
|
584
|
+
protocolDid,
|
|
585
|
+
protocolName: String(raw.protocolName || protocolDid).trim(),
|
|
586
|
+
sourceRoomId,
|
|
587
|
+
sourceLabel,
|
|
588
|
+
...raw.path ? { path: String(raw.path) } : {}
|
|
589
|
+
};
|
|
590
|
+
}).filter((item) => item !== null);
|
|
591
|
+
}
|
|
574
592
|
registerAction({
|
|
575
593
|
type: "qi/pod.list-domain-flows",
|
|
576
594
|
can: "pod/list-domain-flows",
|
|
577
595
|
sideEffect: false,
|
|
578
596
|
defaultRequiresConfirmation: false,
|
|
579
|
-
outputSchema: [
|
|
597
|
+
outputSchema: [
|
|
598
|
+
{
|
|
599
|
+
path: "selectedProtocolTemplates",
|
|
600
|
+
displayName: "Selected Protocol Templates",
|
|
601
|
+
type: "array",
|
|
602
|
+
description: "Selected protocol templates with protocol DID and source room ID"
|
|
603
|
+
},
|
|
604
|
+
{ path: "selectedFlowDids", displayName: "Selected Flow Room IDs", type: "array", description: "Source Matrix room IDs for selected templates" },
|
|
605
|
+
{ path: "flowTemplateConfig", displayName: "Flow Template Config", type: "object", description: "Event payload consumed by POD signing/import steps" }
|
|
606
|
+
],
|
|
607
|
+
events: [
|
|
608
|
+
{
|
|
609
|
+
name: "configured",
|
|
610
|
+
displayName: "Flow Templates Configured",
|
|
611
|
+
description: "Fires when protocol flow templates are selected for the POD.",
|
|
612
|
+
payloadSchema: [
|
|
613
|
+
{
|
|
614
|
+
path: "flowTemplateConfig",
|
|
615
|
+
displayName: "Flow Template Config",
|
|
616
|
+
type: "object",
|
|
617
|
+
description: "Selected templates grouped by their protocol DID for later import"
|
|
618
|
+
}
|
|
619
|
+
],
|
|
620
|
+
pendingDisplayFields: ["flowTemplateConfig.templateCount", "flowTemplateConfig.protocolCount"]
|
|
621
|
+
}
|
|
622
|
+
],
|
|
580
623
|
run: async (inputs) => {
|
|
581
|
-
const
|
|
582
|
-
|
|
624
|
+
const selectedProtocolTemplates = normalizeSelectedTemplates(inputs.selectedProtocolTemplates);
|
|
625
|
+
const selectedFlowDids = selectedProtocolTemplates.length > 0 ? selectedProtocolTemplates.map((template) => template.sourceRoomId) : Array.isArray(inputs.selectedFlowDids) ? inputs.selectedFlowDids : [];
|
|
626
|
+
const protocolCount = new Set(selectedProtocolTemplates.map((template) => template.protocolDid)).size;
|
|
627
|
+
const flowTemplateConfig = {
|
|
628
|
+
selectedTemplates: selectedProtocolTemplates,
|
|
629
|
+
templateCount: selectedProtocolTemplates.length,
|
|
630
|
+
protocolCount
|
|
631
|
+
};
|
|
632
|
+
return {
|
|
633
|
+
output: { selectedProtocolTemplates, selectedFlowDids, flowTemplateConfig },
|
|
634
|
+
events: [{ name: "configured", payload: { flowTemplateConfig } }]
|
|
635
|
+
};
|
|
583
636
|
}
|
|
584
637
|
});
|
|
585
638
|
|
|
@@ -2669,6 +2722,89 @@ function parseContextInput(value) {
|
|
|
2669
2722
|
return key && val ? { key, val } : null;
|
|
2670
2723
|
}).filter((entry) => entry !== null);
|
|
2671
2724
|
}
|
|
2725
|
+
function getSelectedProtocolTemplates(flowTemplateConfig) {
|
|
2726
|
+
const raw = flowTemplateConfig?.selectedTemplates;
|
|
2727
|
+
if (!Array.isArray(raw)) return [];
|
|
2728
|
+
return raw.map((item) => {
|
|
2729
|
+
if (!item || typeof item !== "object") return null;
|
|
2730
|
+
const record = item;
|
|
2731
|
+
const protocolDid = String(record.protocolDid || "").trim();
|
|
2732
|
+
const sourceRoomId = String(record.sourceRoomId || "").trim();
|
|
2733
|
+
if (!protocolDid || !sourceRoomId) return null;
|
|
2734
|
+
const sourceLabel = String(record.sourceLabel || record.label || "").trim();
|
|
2735
|
+
return {
|
|
2736
|
+
protocolDid,
|
|
2737
|
+
sourceRoomId,
|
|
2738
|
+
...sourceLabel ? { sourceLabel } : {}
|
|
2739
|
+
};
|
|
2740
|
+
}).filter((item) => item !== null);
|
|
2741
|
+
}
|
|
2742
|
+
function groupTemplatesByProtocol(templates) {
|
|
2743
|
+
const grouped = /* @__PURE__ */ new Map();
|
|
2744
|
+
for (const template of templates) {
|
|
2745
|
+
const existing = grouped.get(template.protocolDid) || [];
|
|
2746
|
+
existing.push({
|
|
2747
|
+
sourceRoomId: template.sourceRoomId,
|
|
2748
|
+
...template.sourceLabel ? { sourceLabel: template.sourceLabel } : {}
|
|
2749
|
+
});
|
|
2750
|
+
grouped.set(template.protocolDid, existing);
|
|
2751
|
+
}
|
|
2752
|
+
return grouped;
|
|
2753
|
+
}
|
|
2754
|
+
var DOMAIN_SIGN_CACHE_KEY = "domainSign";
|
|
2755
|
+
function getDomainSignCheckpointKey(inputs, ctx) {
|
|
2756
|
+
return String(ctx.pendingInvocation?.id || inputs.pendingInvocationId || inputs.invocationId || "manual");
|
|
2757
|
+
}
|
|
2758
|
+
function readDomainSignCheckpoint(ctx, key) {
|
|
2759
|
+
const cache = ctx.runtime?.get?.(ctx.nodeId)?.cache;
|
|
2760
|
+
const bucket = cache?.[DOMAIN_SIGN_CACHE_KEY];
|
|
2761
|
+
if (!bucket || typeof bucket !== "object") return void 0;
|
|
2762
|
+
const checkpoint = bucket[key];
|
|
2763
|
+
return checkpoint && typeof checkpoint === "object" ? checkpoint : void 0;
|
|
2764
|
+
}
|
|
2765
|
+
function writeDomainSignCheckpoint(ctx, key, checkpoint) {
|
|
2766
|
+
if (!ctx.runtime?.get || !ctx.runtime?.update || !ctx.nodeId) return;
|
|
2767
|
+
const current = ctx.runtime.get(ctx.nodeId) || {};
|
|
2768
|
+
const cache = current.cache && typeof current.cache === "object" ? current.cache : {};
|
|
2769
|
+
const bucket = cache[DOMAIN_SIGN_CACHE_KEY] && typeof cache[DOMAIN_SIGN_CACHE_KEY] === "object" ? cache[DOMAIN_SIGN_CACHE_KEY] : {};
|
|
2770
|
+
ctx.runtime.update(ctx.nodeId, {
|
|
2771
|
+
cache: {
|
|
2772
|
+
...cache,
|
|
2773
|
+
[DOMAIN_SIGN_CACHE_KEY]: {
|
|
2774
|
+
...bucket,
|
|
2775
|
+
[key]: checkpoint
|
|
2776
|
+
}
|
|
2777
|
+
}
|
|
2778
|
+
});
|
|
2779
|
+
}
|
|
2780
|
+
function buildCompletedDomainSignResult(output) {
|
|
2781
|
+
const payload = {
|
|
2782
|
+
entityDid: output.entityDid,
|
|
2783
|
+
governanceGroupCoreAddress: output.governanceGroupCoreAddress || "",
|
|
2784
|
+
transactionHash: output.transactionHash || "",
|
|
2785
|
+
linkedResourceTransactionHash: output.linkedResourceTransactionHash || "",
|
|
2786
|
+
...output.parentLinkedEntityTransactionHash ? { parentLinkedEntityTransactionHash: output.parentLinkedEntityTransactionHash } : {}
|
|
2787
|
+
};
|
|
2788
|
+
return {
|
|
2789
|
+
output,
|
|
2790
|
+
events: [
|
|
2791
|
+
{
|
|
2792
|
+
name: "created",
|
|
2793
|
+
payload
|
|
2794
|
+
}
|
|
2795
|
+
]
|
|
2796
|
+
};
|
|
2797
|
+
}
|
|
2798
|
+
function readDidInput(value) {
|
|
2799
|
+
if (typeof value !== "string") return "";
|
|
2800
|
+
const did = value.trim();
|
|
2801
|
+
if (!did || did === "null" || did === "undefined") return "";
|
|
2802
|
+
return did.startsWith("did:") ? did : "";
|
|
2803
|
+
}
|
|
2804
|
+
function getSelectedParentEntityDid(inputs) {
|
|
2805
|
+
if (inputs.skipped === true || inputs.parentSkipped === true) return "";
|
|
2806
|
+
return readDidInput(inputs.selectedEntityDid) || readDidInput(inputs.parentDid) || readDidInput(inputs.parentDID);
|
|
2807
|
+
}
|
|
2672
2808
|
function parseDuration(raw) {
|
|
2673
2809
|
const seconds = parseInt(raw, 10) || 0;
|
|
2674
2810
|
if (seconds % (7 * 86400) === 0) return { amount: seconds / (7 * 86400), unit: "weeks" };
|
|
@@ -2755,6 +2891,36 @@ registerAction({
|
|
|
2755
2891
|
displayName: "Linked Resource Transaction Hash",
|
|
2756
2892
|
type: "string",
|
|
2757
2893
|
description: "The on-chain transaction hash for adding the domain card linked resource"
|
|
2894
|
+
},
|
|
2895
|
+
{
|
|
2896
|
+
path: "parentEntityDid",
|
|
2897
|
+
displayName: "Parent Entity DID",
|
|
2898
|
+
type: "string",
|
|
2899
|
+
description: "The selected parent entity DID that was updated with the new POD linked entity"
|
|
2900
|
+
},
|
|
2901
|
+
{
|
|
2902
|
+
path: "parentLinkedEntityTransactionHash",
|
|
2903
|
+
displayName: "Parent Linked Entity Transaction Hash",
|
|
2904
|
+
type: "string",
|
|
2905
|
+
description: "The on-chain transaction hash for linking the new POD to the selected parent entity"
|
|
2906
|
+
},
|
|
2907
|
+
{
|
|
2908
|
+
path: "flowTemplateConfig",
|
|
2909
|
+
displayName: "Flow Template Config",
|
|
2910
|
+
type: "object",
|
|
2911
|
+
description: "Selected protocol templates captured before POD creation"
|
|
2912
|
+
},
|
|
2913
|
+
{
|
|
2914
|
+
path: "domainSpaces",
|
|
2915
|
+
displayName: "Domain Spaces",
|
|
2916
|
+
type: "object",
|
|
2917
|
+
description: "Matrix space structure sourced for the new domain"
|
|
2918
|
+
},
|
|
2919
|
+
{
|
|
2920
|
+
path: "protocolTemplateImports",
|
|
2921
|
+
displayName: "Protocol Template Imports",
|
|
2922
|
+
type: "array",
|
|
2923
|
+
description: "Import results for selected protocol templates"
|
|
2758
2924
|
}
|
|
2759
2925
|
],
|
|
2760
2926
|
events: [
|
|
@@ -2776,22 +2942,19 @@ registerAction({
|
|
|
2776
2942
|
displayName: "Linked Resource Transaction Hash",
|
|
2777
2943
|
type: "string",
|
|
2778
2944
|
description: "On-chain transaction hash for adding the domain card linked resource"
|
|
2945
|
+
},
|
|
2946
|
+
{
|
|
2947
|
+
path: "parentLinkedEntityTransactionHash",
|
|
2948
|
+
displayName: "Parent Linked Entity Transaction Hash",
|
|
2949
|
+
type: "string",
|
|
2950
|
+
description: "On-chain transaction hash for linking the new POD to the selected parent entity"
|
|
2779
2951
|
}
|
|
2780
2952
|
],
|
|
2781
2953
|
pendingDisplayFields: ["entityDid", "governanceGroupCoreAddress"]
|
|
2782
2954
|
}
|
|
2783
2955
|
],
|
|
2784
2956
|
run: async (inputs, ctx) => {
|
|
2785
|
-
const handlers = ctx.handlers;
|
|
2786
|
-
if (!handlers) {
|
|
2787
|
-
throw new Error("Handlers not available");
|
|
2788
|
-
}
|
|
2789
|
-
if (!handlers.requestPin) throw new Error("requestPin handler not available");
|
|
2790
|
-
if (!handlers.signCredential) throw new Error("signCredential handler not implemented");
|
|
2791
|
-
if (!handlers.publicFileUpload) throw new Error("publicFileUpload handler not available");
|
|
2792
|
-
if (!handlers.createDomain) throw new Error("createDomain handler not implemented");
|
|
2793
|
-
if (!handlers.createAddLinkedResourceMessage) throw new Error("createAddLinkedResourceMessage handler not implemented");
|
|
2794
|
-
if (!handlers.executeTransaction) throw new Error("executeTransaction handler not implemented");
|
|
2957
|
+
const handlers = ctx.handlers || {};
|
|
2795
2958
|
let domainCardData;
|
|
2796
2959
|
if (typeof inputs.domainCardData === "string") {
|
|
2797
2960
|
try {
|
|
@@ -2814,99 +2977,276 @@ registerAction({
|
|
|
2814
2977
|
d.setFullYear(d.getFullYear() + 100);
|
|
2815
2978
|
return d.toISOString();
|
|
2816
2979
|
})();
|
|
2817
|
-
let governanceGroupLinkedEntities = [];
|
|
2818
|
-
let governanceGroupCoreAddress = "";
|
|
2819
2980
|
const govConfig = parseJsonInput(inputs.governanceConfig);
|
|
2820
2981
|
const memberConfig = parseJsonInput(inputs.memberConfig);
|
|
2982
|
+
const flowTemplateConfig = parseJsonInput(inputs.flowTemplateConfig);
|
|
2821
2983
|
const context = parseContextInput(inputs.context);
|
|
2822
|
-
|
|
2823
|
-
|
|
2824
|
-
|
|
2825
|
-
|
|
2826
|
-
|
|
2827
|
-
|
|
2828
|
-
|
|
2829
|
-
|
|
2830
|
-
|
|
2831
|
-
|
|
2832
|
-
|
|
2833
|
-
|
|
2834
|
-
|
|
2835
|
-
|
|
2836
|
-
|
|
2837
|
-
|
|
2984
|
+
const selectedParentEntityDid = getSelectedParentEntityDid(inputs);
|
|
2985
|
+
const selectedProtocolTemplates = getSelectedProtocolTemplates(flowTemplateConfig);
|
|
2986
|
+
const checkpointKey = getDomainSignCheckpointKey(inputs, ctx);
|
|
2987
|
+
let checkpoint = readDomainSignCheckpoint(ctx, checkpointKey) || {
|
|
2988
|
+
invocationId: checkpointKey,
|
|
2989
|
+
status: "running",
|
|
2990
|
+
updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
2991
|
+
completedSteps: {}
|
|
2992
|
+
};
|
|
2993
|
+
if (checkpoint.status === "completed" && checkpoint.output) {
|
|
2994
|
+
return buildCompletedDomainSignResult(checkpoint.output);
|
|
2995
|
+
}
|
|
2996
|
+
if (!ctx.handlers) {
|
|
2997
|
+
throw new Error("Handlers not available");
|
|
2998
|
+
}
|
|
2999
|
+
if (typeof handlers.requestPin !== "function") throw new Error("requestPin handler not available");
|
|
3000
|
+
if (typeof handlers.signCredential !== "function") throw new Error("signCredential handler not implemented");
|
|
3001
|
+
if (typeof handlers.publicFileUpload !== "function") throw new Error("publicFileUpload handler not available");
|
|
3002
|
+
if (typeof handlers.createDomain !== "function") throw new Error("createDomain handler not implemented");
|
|
3003
|
+
if (typeof handlers.createAddLinkedResourceMessage !== "function") throw new Error("createAddLinkedResourceMessage handler not implemented");
|
|
3004
|
+
if (typeof handlers.executeTransaction !== "function") throw new Error("executeTransaction handler not implemented");
|
|
3005
|
+
const saveCheckpoint = (updates) => {
|
|
3006
|
+
checkpoint = {
|
|
3007
|
+
...checkpoint,
|
|
3008
|
+
...updates,
|
|
3009
|
+
invocationId: checkpointKey,
|
|
3010
|
+
updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
3011
|
+
completedSteps: {
|
|
3012
|
+
...checkpoint.completedSteps || {},
|
|
3013
|
+
...updates.completedSteps || {}
|
|
2838
3014
|
}
|
|
2839
|
-
|
|
2840
|
-
|
|
2841
|
-
|
|
2842
|
-
const { entityDid: newEntityDid, transactionHash } = await handlers.createDomain({
|
|
2843
|
-
entityType,
|
|
2844
|
-
context: context.length > 0 ? context : void 0,
|
|
2845
|
-
linkedResource: [],
|
|
2846
|
-
linkedEntity: governanceGroupLinkedEntities.length > 0 ? governanceGroupLinkedEntities : void 0,
|
|
2847
|
-
startDate: validFrom,
|
|
2848
|
-
endDate
|
|
2849
|
-
});
|
|
2850
|
-
const issuerDid = handlers.getEntityDid?.() || handlers.getCurrentUser?.()?.address;
|
|
2851
|
-
if (!issuerDid) throw new Error("Unable to determine issuer DID");
|
|
2852
|
-
const credentialSubject = {
|
|
2853
|
-
...domainCardData.credentialSubject,
|
|
2854
|
-
id: newEntityDid
|
|
3015
|
+
};
|
|
3016
|
+
writeDomainSignCheckpoint(ctx, checkpointKey, checkpoint);
|
|
3017
|
+
return checkpoint;
|
|
2855
3018
|
};
|
|
2856
|
-
|
|
2857
|
-
|
|
2858
|
-
|
|
2859
|
-
|
|
2860
|
-
validFrom,
|
|
2861
|
-
validUntil
|
|
2862
|
-
});
|
|
2863
|
-
const pin = await handlers.requestPin({
|
|
2864
|
-
title: "Sign Domain Card",
|
|
2865
|
-
description: "Enter your PIN to sign the Domain Card credential",
|
|
2866
|
-
submitText: "Sign"
|
|
2867
|
-
});
|
|
2868
|
-
const { signedCredential } = await handlers.signCredential({
|
|
2869
|
-
issuerDid,
|
|
2870
|
-
issuerType: "user",
|
|
2871
|
-
credential: unsignedCredential,
|
|
2872
|
-
pin
|
|
2873
|
-
});
|
|
2874
|
-
const credentialBlob = new Blob([JSON.stringify(signedCredential, null, 2)], {
|
|
2875
|
-
type: "application/json"
|
|
2876
|
-
});
|
|
2877
|
-
const credentialFile = new File([credentialBlob], "domainCard.json", {
|
|
2878
|
-
type: "application/json"
|
|
2879
|
-
});
|
|
2880
|
-
const uploadResult = await handlers.publicFileUpload(credentialFile);
|
|
2881
|
-
const domainCardLinkedResource = buildDomainCardLinkedResource({
|
|
2882
|
-
entityDid: newEntityDid,
|
|
2883
|
-
cid: uploadResult.cid,
|
|
2884
|
-
serviceEndpoint: uploadResult.url,
|
|
2885
|
-
description: `Domain Card for ${domainCardData.credentialSubject?.name || "Domain"}`
|
|
2886
|
-
});
|
|
2887
|
-
const addLinkedResourceMessage = await handlers.createAddLinkedResourceMessage({
|
|
2888
|
-
entityDid: newEntityDid,
|
|
2889
|
-
linkedResource: domainCardLinkedResource
|
|
2890
|
-
});
|
|
2891
|
-
const addLinkedResourceResult = await handlers.executeTransaction({
|
|
2892
|
-
messages: [addLinkedResourceMessage],
|
|
2893
|
-
memo: ""
|
|
3019
|
+
saveCheckpoint({
|
|
3020
|
+
status: "running",
|
|
3021
|
+
error: void 0,
|
|
3022
|
+
flowTemplateConfig
|
|
2894
3023
|
});
|
|
2895
|
-
|
|
2896
|
-
|
|
2897
|
-
|
|
2898
|
-
|
|
2899
|
-
|
|
2900
|
-
|
|
3024
|
+
try {
|
|
3025
|
+
let governanceGroupLinkedEntities = checkpoint.governanceGroupLinkedEntities || [];
|
|
3026
|
+
let governanceGroupCoreAddress = checkpoint.governanceGroupCoreAddress || "";
|
|
3027
|
+
if (govConfig && handlers.createGovernanceGroup && !checkpoint.completedSteps?.createGovernanceGroup) {
|
|
3028
|
+
const groupType = govConfig.groupType;
|
|
3029
|
+
const governance = govConfig.governance || {};
|
|
3030
|
+
const config = buildGroupConfig(groupType, governance, memberConfig);
|
|
3031
|
+
const groupResult = await handlers.createGovernanceGroup({
|
|
3032
|
+
groupType,
|
|
3033
|
+
name: govConfig.groupName || domainCardData.credentialSubject?.name || "Governance Group",
|
|
3034
|
+
config
|
|
3035
|
+
});
|
|
3036
|
+
governanceGroupCoreAddress = groupResult.coreAddress;
|
|
3037
|
+
governanceGroupLinkedEntities = [
|
|
3038
|
+
{
|
|
3039
|
+
id: `{id}#${governanceGroupCoreAddress}`,
|
|
3040
|
+
type: "group",
|
|
3041
|
+
relationship: "governs",
|
|
3042
|
+
service: ""
|
|
3043
|
+
}
|
|
3044
|
+
];
|
|
3045
|
+
saveCheckpoint({
|
|
3046
|
+
governanceGroupCoreAddress,
|
|
3047
|
+
governanceGroupLinkedEntities,
|
|
3048
|
+
completedSteps: { createGovernanceGroup: true }
|
|
3049
|
+
});
|
|
3050
|
+
} else if (!govConfig) {
|
|
3051
|
+
saveCheckpoint({ completedSteps: { createGovernanceGroup: true } });
|
|
3052
|
+
}
|
|
3053
|
+
const issuerDid = handlers.getEntityDid?.() || handlers.getCurrentUser?.()?.address;
|
|
3054
|
+
if (!issuerDid) throw new Error("Unable to determine issuer DID");
|
|
3055
|
+
const signAndUploadDomainCard = async (entityDid) => {
|
|
3056
|
+
const credentialSubject = {
|
|
3057
|
+
...domainCardData.credentialSubject,
|
|
3058
|
+
id: entityDid
|
|
3059
|
+
};
|
|
3060
|
+
const unsignedCredential = buildVerifiableCredential({
|
|
3061
|
+
entityDid,
|
|
3062
|
+
issuerDid,
|
|
3063
|
+
credentialSubject,
|
|
3064
|
+
validFrom,
|
|
3065
|
+
validUntil
|
|
3066
|
+
});
|
|
3067
|
+
const pin = await handlers.requestPin({
|
|
3068
|
+
title: "Sign Domain Card",
|
|
3069
|
+
description: "Enter your PIN to sign the Domain Card credential",
|
|
3070
|
+
submitText: "Sign"
|
|
3071
|
+
});
|
|
3072
|
+
const { signedCredential } = await handlers.signCredential({
|
|
3073
|
+
issuerDid,
|
|
3074
|
+
issuerType: "user",
|
|
3075
|
+
credential: unsignedCredential,
|
|
3076
|
+
pin
|
|
3077
|
+
});
|
|
3078
|
+
const credentialBlob = new Blob([JSON.stringify(signedCredential, null, 2)], {
|
|
3079
|
+
type: "application/json"
|
|
3080
|
+
});
|
|
3081
|
+
const credentialFile = new File([credentialBlob], "domainCard.json", {
|
|
3082
|
+
type: "application/json"
|
|
3083
|
+
});
|
|
3084
|
+
const uploadResult = await handlers.publicFileUpload(credentialFile);
|
|
3085
|
+
return {
|
|
3086
|
+
...buildDomainCardLinkedResource({
|
|
3087
|
+
entityDid,
|
|
3088
|
+
cid: uploadResult.cid,
|
|
3089
|
+
serviceEndpoint: uploadResult.url,
|
|
3090
|
+
description: `Domain Card for ${domainCardData.credentialSubject?.name || "Domain"}`
|
|
3091
|
+
}),
|
|
3092
|
+
id: "{id}#dmn"
|
|
3093
|
+
};
|
|
3094
|
+
};
|
|
3095
|
+
const endDate = domainCardData.endDate || validUntil;
|
|
3096
|
+
let newEntityDid = checkpoint.entityDid || "";
|
|
3097
|
+
let transactionHash = checkpoint.transactionHash || "";
|
|
3098
|
+
let linkedResourceTransactionHash = checkpoint.linkedResourceTransactionHash || "";
|
|
3099
|
+
const parentEntityDid = checkpoint.parentEntityDid || selectedParentEntityDid;
|
|
3100
|
+
let parentLinkedEntity = checkpoint.parentLinkedEntity;
|
|
3101
|
+
let parentLinkedEntityTransactionHash = checkpoint.parentLinkedEntityTransactionHash || "";
|
|
3102
|
+
let domainCardLinkedResource = checkpoint.domainCardLinkedResource;
|
|
3103
|
+
if (!checkpoint.completedSteps?.createDomain || !newEntityDid || !transactionHash) {
|
|
3104
|
+
const createResult = await handlers.createDomain({
|
|
3105
|
+
entityType,
|
|
3106
|
+
context: context.length > 0 ? context : void 0,
|
|
3107
|
+
linkedResource: [],
|
|
3108
|
+
linkedEntity: governanceGroupLinkedEntities.length > 0 ? governanceGroupLinkedEntities : void 0,
|
|
3109
|
+
startDate: validFrom,
|
|
3110
|
+
endDate
|
|
3111
|
+
});
|
|
3112
|
+
newEntityDid = createResult.entityDid;
|
|
3113
|
+
transactionHash = createResult.transactionHash;
|
|
3114
|
+
saveCheckpoint({
|
|
3115
|
+
entityDid: newEntityDid,
|
|
3116
|
+
transactionHash,
|
|
3117
|
+
completedSteps: { createDomain: true }
|
|
3118
|
+
});
|
|
3119
|
+
}
|
|
3120
|
+
if (!checkpoint.completedSteps?.signAndUploadDomainCard || !domainCardLinkedResource) {
|
|
3121
|
+
domainCardLinkedResource = await signAndUploadDomainCard(newEntityDid);
|
|
3122
|
+
saveCheckpoint({
|
|
3123
|
+
domainCardLinkedResource,
|
|
3124
|
+
completedSteps: { signAndUploadDomainCard: true }
|
|
3125
|
+
});
|
|
3126
|
+
}
|
|
3127
|
+
if (!checkpoint.completedSteps?.addLinkedResource || !linkedResourceTransactionHash) {
|
|
3128
|
+
const addLinkedResourceMessage = await handlers.createAddLinkedResourceMessage({
|
|
3129
|
+
entityDid: newEntityDid,
|
|
3130
|
+
linkedResource: domainCardLinkedResource
|
|
3131
|
+
});
|
|
3132
|
+
const addLinkedResourceResult = await handlers.executeTransaction({
|
|
3133
|
+
messages: [addLinkedResourceMessage],
|
|
3134
|
+
memo: ""
|
|
3135
|
+
});
|
|
3136
|
+
linkedResourceTransactionHash = String(addLinkedResourceResult?.transactionHash || "");
|
|
3137
|
+
if (!linkedResourceTransactionHash) {
|
|
3138
|
+
throw new Error("Linked resource transaction completed but no transaction hash received");
|
|
3139
|
+
}
|
|
3140
|
+
saveCheckpoint({
|
|
3141
|
+
linkedResourceTransactionHash,
|
|
3142
|
+
completedSteps: { addLinkedResource: true }
|
|
3143
|
+
});
|
|
3144
|
+
}
|
|
3145
|
+
if (parentEntityDid && (!checkpoint.completedSteps?.addParentLinkedEntity || !parentLinkedEntityTransactionHash)) {
|
|
3146
|
+
if (typeof handlers.createAddLinkedEntityMessage !== "function") {
|
|
3147
|
+
throw new Error("createAddLinkedEntityMessage handler not implemented");
|
|
3148
|
+
}
|
|
3149
|
+
parentLinkedEntity = parentLinkedEntity || {
|
|
3150
|
+
id: newEntityDid,
|
|
3151
|
+
type: entityType,
|
|
3152
|
+
relationship: "manages",
|
|
3153
|
+
service: ""
|
|
3154
|
+
};
|
|
3155
|
+
const addParentLinkedEntityMessage = await handlers.createAddLinkedEntityMessage({
|
|
3156
|
+
entityDid: parentEntityDid,
|
|
3157
|
+
linkedEntity: parentLinkedEntity
|
|
3158
|
+
});
|
|
3159
|
+
const addParentLinkedEntityResult = await handlers.executeTransaction({
|
|
3160
|
+
messages: [addParentLinkedEntityMessage],
|
|
3161
|
+
memo: ""
|
|
3162
|
+
});
|
|
3163
|
+
parentLinkedEntityTransactionHash = String(addParentLinkedEntityResult?.transactionHash || "");
|
|
3164
|
+
if (!parentLinkedEntityTransactionHash) {
|
|
3165
|
+
throw new Error("Parent linked entity transaction completed but no transaction hash received");
|
|
3166
|
+
}
|
|
3167
|
+
saveCheckpoint({
|
|
3168
|
+
parentEntityDid,
|
|
3169
|
+
parentLinkedEntity,
|
|
3170
|
+
parentLinkedEntityTransactionHash,
|
|
3171
|
+
completedSteps: { addParentLinkedEntity: true }
|
|
3172
|
+
});
|
|
3173
|
+
} else if (!parentEntityDid) {
|
|
3174
|
+
saveCheckpoint({ completedSteps: { addParentLinkedEntity: true } });
|
|
3175
|
+
}
|
|
3176
|
+
let domainSpaces = checkpoint.domainSpaces;
|
|
3177
|
+
let protocolTemplateImports = checkpoint.protocolTemplateImports || [];
|
|
3178
|
+
if (handlers.sourceDomainSpaces && (!checkpoint.completedSteps?.sourceDomainSpaces || !domainSpaces)) {
|
|
3179
|
+
domainSpaces = await handlers.sourceDomainSpaces({ entityDid: newEntityDid });
|
|
3180
|
+
if (!domainSpaces?.success) {
|
|
3181
|
+
throw new Error("Domain spaces could not be sourced for the newly created domain");
|
|
3182
|
+
}
|
|
3183
|
+
saveCheckpoint({
|
|
3184
|
+
domainSpaces,
|
|
3185
|
+
completedSteps: { sourceDomainSpaces: true }
|
|
3186
|
+
});
|
|
3187
|
+
} else if (!handlers.sourceDomainSpaces) {
|
|
3188
|
+
saveCheckpoint({ completedSteps: { sourceDomainSpaces: true } });
|
|
3189
|
+
}
|
|
3190
|
+
if (selectedProtocolTemplates.length > 0 && !checkpoint.completedSteps?.importTemplates) {
|
|
3191
|
+
if (!handlers.sourceDomainSpaces) {
|
|
3192
|
+
throw new Error("sourceDomainSpaces handler is required to import selected protocol templates");
|
|
3193
|
+
}
|
|
3194
|
+
if (!handlers.importProtocolTemplatesToSpace) {
|
|
3195
|
+
throw new Error("importProtocolTemplatesToSpace handler is required to import selected protocol templates");
|
|
3196
|
+
}
|
|
3197
|
+
const targetFlowsSubspaceId = domainSpaces?.subspaces?.["domain flows"]?.space_id;
|
|
3198
|
+
if (!targetFlowsSubspaceId) {
|
|
3199
|
+
throw new Error("Domain flows subspace was not returned by sourceDomainSpaces");
|
|
3200
|
+
}
|
|
3201
|
+
const groupedTemplates = groupTemplatesByProtocol(selectedProtocolTemplates);
|
|
3202
|
+
protocolTemplateImports = await Promise.all(
|
|
3203
|
+
Array.from(groupedTemplates.entries()).map(async ([protocolDid, templates]) => {
|
|
3204
|
+
const result = await handlers.importProtocolTemplatesToSpace({
|
|
3205
|
+
protocolDid,
|
|
3206
|
+
entityDid: newEntityDid,
|
|
3207
|
+
targetFlowsSubspaceId,
|
|
3208
|
+
templates
|
|
3209
|
+
});
|
|
3210
|
+
return { protocolDid, imported: result.imported };
|
|
3211
|
+
})
|
|
3212
|
+
);
|
|
3213
|
+
saveCheckpoint({
|
|
3214
|
+
protocolTemplateImports,
|
|
3215
|
+
completedSteps: { importTemplates: true }
|
|
3216
|
+
});
|
|
3217
|
+
} else if (selectedProtocolTemplates.length === 0) {
|
|
3218
|
+
saveCheckpoint({
|
|
3219
|
+
protocolTemplateImports,
|
|
3220
|
+
completedSteps: { importTemplates: true }
|
|
3221
|
+
});
|
|
3222
|
+
}
|
|
3223
|
+
const output = {
|
|
2901
3224
|
entityDid: newEntityDid,
|
|
2902
3225
|
governanceGroupCoreAddress,
|
|
2903
3226
|
linkedEntities: governanceGroupLinkedEntities,
|
|
2904
3227
|
linkedResources: [domainCardLinkedResource],
|
|
3228
|
+
parentEntityDid,
|
|
3229
|
+
parentLinkedEntity,
|
|
3230
|
+
flowTemplateConfig,
|
|
3231
|
+
domainSpaces,
|
|
3232
|
+
protocolTemplateImports,
|
|
2905
3233
|
transactionHash,
|
|
2906
|
-
linkedResourceTransactionHash
|
|
2907
|
-
|
|
2908
|
-
|
|
2909
|
-
|
|
3234
|
+
linkedResourceTransactionHash,
|
|
3235
|
+
parentLinkedEntityTransactionHash
|
|
3236
|
+
};
|
|
3237
|
+
saveCheckpoint({
|
|
3238
|
+
status: "completed",
|
|
3239
|
+
output
|
|
3240
|
+
});
|
|
3241
|
+
return buildCompletedDomainSignResult(output);
|
|
3242
|
+
} catch (error) {
|
|
3243
|
+
const message = error instanceof Error ? error.message : "Domain sign failed";
|
|
3244
|
+
saveCheckpoint({
|
|
3245
|
+
status: "failed",
|
|
3246
|
+
error: message
|
|
3247
|
+
});
|
|
3248
|
+
throw error;
|
|
3249
|
+
}
|
|
2910
3250
|
}
|
|
2911
3251
|
});
|
|
2912
3252
|
|
|
@@ -3078,9 +3418,7 @@ registerAction({
|
|
|
3078
3418
|
}
|
|
3079
3419
|
const verb = String(inputs.verb || "").trim().toLowerCase();
|
|
3080
3420
|
if (verb !== "propose" && verb !== "execute" && verb !== "check") {
|
|
3081
|
-
throw new Error(
|
|
3082
|
-
'verb is required and must be one of: "propose", "execute", "check"'
|
|
3083
|
-
);
|
|
3421
|
+
throw new Error('verb is required and must be one of: "propose", "execute", "check"');
|
|
3084
3422
|
}
|
|
3085
3423
|
const paymentBlockId = String(inputs.paymentBlockId || "").trim();
|
|
3086
3424
|
if (!paymentBlockId) {
|
|
@@ -3108,6 +3446,15 @@ registerAction({
|
|
|
3108
3446
|
verb,
|
|
3109
3447
|
rowCount: rowIds.length,
|
|
3110
3448
|
paymentBlockId
|
|
3449
|
+
},
|
|
3450
|
+
completion: {
|
|
3451
|
+
state: "awaiting_readback",
|
|
3452
|
+
readBack: {
|
|
3453
|
+
kind: "paymentRows",
|
|
3454
|
+
paymentBlockId,
|
|
3455
|
+
rowIds,
|
|
3456
|
+
verb
|
|
3457
|
+
}
|
|
3111
3458
|
}
|
|
3112
3459
|
};
|
|
3113
3460
|
}
|
|
@@ -5275,6 +5622,7 @@ function toSupportedDID(did) {
|
|
|
5275
5622
|
}
|
|
5276
5623
|
function normalizeDid(did) {
|
|
5277
5624
|
if (did.startsWith("did:")) return did;
|
|
5625
|
+
if (did.startsWith("ixo1")) return `did:ixo:${did}`;
|
|
5278
5626
|
if (!did.startsWith("@did-")) return did;
|
|
5279
5627
|
const [localpart] = did.split(":");
|
|
5280
5628
|
const parts = localpart.split("-");
|
|
@@ -5363,7 +5711,7 @@ var createUcanService = (config) => {
|
|
|
5363
5711
|
const capabilities = [{ can: "flow/*", with: uri }];
|
|
5364
5712
|
if (handlers.createSignerSession && handlers.createDelegationWithSession) {
|
|
5365
5713
|
const session = await handlers.createSignerSession({
|
|
5366
|
-
did:
|
|
5714
|
+
did: normalizedOwnerDid,
|
|
5367
5715
|
didType: issuerType,
|
|
5368
5716
|
entityRoomId,
|
|
5369
5717
|
pin,
|
|
@@ -5371,15 +5719,15 @@ var createUcanService = (config) => {
|
|
|
5371
5719
|
});
|
|
5372
5720
|
const result = await handlers.createDelegationWithSession({
|
|
5373
5721
|
sessionId: session.sessionId,
|
|
5374
|
-
audience:
|
|
5722
|
+
audience: normalizedOwnerDid,
|
|
5375
5723
|
capabilities,
|
|
5376
5724
|
proofs: []
|
|
5377
5725
|
});
|
|
5378
5726
|
const storedDelegation2 = {
|
|
5379
5727
|
cid: result.cid,
|
|
5380
5728
|
delegation: result.delegation,
|
|
5381
|
-
issuerDid:
|
|
5382
|
-
audienceDid:
|
|
5729
|
+
issuerDid: normalizedOwnerDid,
|
|
5730
|
+
audienceDid: normalizedOwnerDid,
|
|
5383
5731
|
capabilities,
|
|
5384
5732
|
createdAt: Date.now(),
|
|
5385
5733
|
format: "car",
|
|
@@ -5420,7 +5768,7 @@ var createUcanService = (config) => {
|
|
|
5420
5768
|
const proofCids = proofs;
|
|
5421
5769
|
if (handlers.createSignerSession && handlers.createDelegationWithSession) {
|
|
5422
5770
|
const session = await handlers.createSignerSession({
|
|
5423
|
-
did:
|
|
5771
|
+
did: normalizedIssuerDid,
|
|
5424
5772
|
didType: issuerType,
|
|
5425
5773
|
entityRoomId,
|
|
5426
5774
|
pin,
|
|
@@ -5429,7 +5777,7 @@ var createUcanService = (config) => {
|
|
|
5429
5777
|
const proofCars = await getProofCars(proofCids);
|
|
5430
5778
|
const result = await handlers.createDelegationWithSession({
|
|
5431
5779
|
sessionId: session.sessionId,
|
|
5432
|
-
audience,
|
|
5780
|
+
audience: normalizedAudienceDid,
|
|
5433
5781
|
capabilities,
|
|
5434
5782
|
proofs: proofCars,
|
|
5435
5783
|
expiration: expiration ? Math.floor(expiration / 1e3) : void 0
|
|
@@ -5437,8 +5785,8 @@ var createUcanService = (config) => {
|
|
|
5437
5785
|
const storedDelegation2 = {
|
|
5438
5786
|
cid: result.cid,
|
|
5439
5787
|
delegation: result.delegation,
|
|
5440
|
-
issuerDid,
|
|
5441
|
-
audienceDid:
|
|
5788
|
+
issuerDid: normalizedIssuerDid,
|
|
5789
|
+
audienceDid: normalizedAudienceDid,
|
|
5442
5790
|
capabilities,
|
|
5443
5791
|
expiration,
|
|
5444
5792
|
createdAt: Date.now(),
|
|
@@ -5491,7 +5839,7 @@ var createUcanService = (config) => {
|
|
|
5491
5839
|
const delegations = delegationStore.getByAudience(audienceDid);
|
|
5492
5840
|
if (delegations.length === 0) {
|
|
5493
5841
|
const root = delegationStore.getRoot();
|
|
5494
|
-
if (root && root.audienceDid === audienceDid) {
|
|
5842
|
+
if (root && normalizeDid(root.audienceDid) === normalizeDid(audienceDid)) {
|
|
5495
5843
|
return { found: true, proofCids: [root.cid] };
|
|
5496
5844
|
}
|
|
5497
5845
|
return { found: false, error: "No delegations found for actor" };
|
|
@@ -5547,7 +5895,7 @@ var createUcanService = (config) => {
|
|
|
5547
5895
|
const isFlowScoped = capability.can === "flow/*" || capability.can.startsWith("flow/");
|
|
5548
5896
|
if (isFlowScoped) {
|
|
5549
5897
|
const root = proofChain[proofChain.length - 1];
|
|
5550
|
-
if (root.issuerDid !== flowOwnerDid) {
|
|
5898
|
+
if (normalizeDid(root.issuerDid) !== normalizeDid(flowOwnerDid)) {
|
|
5551
5899
|
return { valid: false, error: `Root issuer ${root.issuerDid} is not flow owner ${flowOwnerDid}` };
|
|
5552
5900
|
}
|
|
5553
5901
|
}
|
|
@@ -5555,7 +5903,8 @@ var createUcanService = (config) => {
|
|
|
5555
5903
|
};
|
|
5556
5904
|
const createAndValidateInvocation = async (params, _flowId, _blockId) => {
|
|
5557
5905
|
const { invokerDid, invokerType, entityRoomId, capability, proofs, pin } = params;
|
|
5558
|
-
const
|
|
5906
|
+
const normalizedInvokerDid = normalizeDid(invokerDid);
|
|
5907
|
+
const validation = await validateDelegationChain(normalizedInvokerDid, capability);
|
|
5559
5908
|
if (!validation.valid) {
|
|
5560
5909
|
return {
|
|
5561
5910
|
cid: "",
|
|
@@ -5564,11 +5913,11 @@ var createUcanService = (config) => {
|
|
|
5564
5913
|
error: validation.error
|
|
5565
5914
|
};
|
|
5566
5915
|
}
|
|
5567
|
-
const audience = params.audience ?? flowOwnerDid;
|
|
5916
|
+
const audience = normalizeDid(params.audience ?? flowOwnerDid);
|
|
5568
5917
|
if (handlers.createSignerSession && handlers.createInvocationWithSession) {
|
|
5569
5918
|
try {
|
|
5570
5919
|
const session = await handlers.createSignerSession({
|
|
5571
|
-
did:
|
|
5920
|
+
did: normalizedInvokerDid,
|
|
5572
5921
|
didType: invokerType,
|
|
5573
5922
|
entityRoomId,
|
|
5574
5923
|
pin,
|
|
@@ -6083,6 +6432,9 @@ var createRuntimeStateManager = (editor) => {
|
|
|
6083
6432
|
}
|
|
6084
6433
|
return createMemoryManager();
|
|
6085
6434
|
};
|
|
6435
|
+
var createYDocRuntimeManager = (yDoc) => {
|
|
6436
|
+
return createYMapManager(yDoc.getMap("runtime"));
|
|
6437
|
+
};
|
|
6086
6438
|
function clearRuntimeForTemplateClone(yDoc) {
|
|
6087
6439
|
const runtime = yDoc.getMap("runtime");
|
|
6088
6440
|
const invocations = yDoc.getMap("invocations");
|
|
@@ -6100,6 +6452,66 @@ function clearRuntimeForTemplateClone(yDoc) {
|
|
|
6100
6452
|
});
|
|
6101
6453
|
}
|
|
6102
6454
|
|
|
6455
|
+
// src/core/types/baseUcan.ts
|
|
6456
|
+
function isRuntimeRef(value) {
|
|
6457
|
+
return typeof value === "object" && value !== null && "$ref" in value && typeof value.$ref === "string";
|
|
6458
|
+
}
|
|
6459
|
+
|
|
6460
|
+
// src/core/lib/flowCompiler/resolveRefs.ts
|
|
6461
|
+
function resolveRuntimeRefs(nb, getNodeOutput2, triggerContext) {
|
|
6462
|
+
return resolveValue(nb, getNodeOutput2, triggerContext);
|
|
6463
|
+
}
|
|
6464
|
+
function resolveValue(value, getNodeOutput2, triggerContext) {
|
|
6465
|
+
if (isRuntimeRef(value)) {
|
|
6466
|
+
return resolveRef(value.$ref, getNodeOutput2, triggerContext);
|
|
6467
|
+
}
|
|
6468
|
+
if (Array.isArray(value)) {
|
|
6469
|
+
return value.map((item) => resolveValue(item, getNodeOutput2, triggerContext));
|
|
6470
|
+
}
|
|
6471
|
+
if (typeof value === "object" && value !== null) {
|
|
6472
|
+
const result = {};
|
|
6473
|
+
for (const [key, val] of Object.entries(value)) {
|
|
6474
|
+
result[key] = resolveValue(val, getNodeOutput2, triggerContext);
|
|
6475
|
+
}
|
|
6476
|
+
return result;
|
|
6477
|
+
}
|
|
6478
|
+
return value;
|
|
6479
|
+
}
|
|
6480
|
+
function resolveRef(ref, getNodeOutput2, triggerContext) {
|
|
6481
|
+
if (ref.startsWith("trigger.payload.")) {
|
|
6482
|
+
if (!triggerContext) {
|
|
6483
|
+
throw new Error(`Trigger ref "${ref}" used outside of a listener invocation context. trigger.payload.* refs are only valid on block.event-triggered blocks.`);
|
|
6484
|
+
}
|
|
6485
|
+
const fieldPath2 = ref.slice("trigger.payload.".length);
|
|
6486
|
+
return getNestedValue(triggerContext.payload, fieldPath2);
|
|
6487
|
+
}
|
|
6488
|
+
if (triggerContext && Object.prototype.hasOwnProperty.call(triggerContext.refSnapshots, ref)) {
|
|
6489
|
+
return triggerContext.refSnapshots[ref];
|
|
6490
|
+
}
|
|
6491
|
+
const outputIndex = ref.indexOf(".output.");
|
|
6492
|
+
if (outputIndex === -1) {
|
|
6493
|
+
throw new Error(`Invalid runtime reference "${ref}". Expected format: "nodeId.output.fieldPath" or "trigger.payload.fieldPath"`);
|
|
6494
|
+
}
|
|
6495
|
+
const nodeId = ref.slice(0, outputIndex);
|
|
6496
|
+
const fieldPath = ref.slice(outputIndex + ".output.".length);
|
|
6497
|
+
const output = getNodeOutput2(nodeId);
|
|
6498
|
+
if (!output) {
|
|
6499
|
+
return void 0;
|
|
6500
|
+
}
|
|
6501
|
+
return getNestedValue(output, fieldPath);
|
|
6502
|
+
}
|
|
6503
|
+
function getNestedValue(obj, path) {
|
|
6504
|
+
const parts = path.split(".");
|
|
6505
|
+
let current = obj;
|
|
6506
|
+
for (const part of parts) {
|
|
6507
|
+
if (current == null || typeof current !== "object") {
|
|
6508
|
+
return void 0;
|
|
6509
|
+
}
|
|
6510
|
+
current = current[part];
|
|
6511
|
+
}
|
|
6512
|
+
return current;
|
|
6513
|
+
}
|
|
6514
|
+
|
|
6103
6515
|
// src/core/lib/flowEngine/versionManifest.ts
|
|
6104
6516
|
var VERSION_MANIFEST = {
|
|
6105
6517
|
"0.3": {
|
|
@@ -6310,11 +6722,6 @@ var executeNode = async ({ node, actorDid, actorType, entityRoomId, context, act
|
|
|
6310
6722
|
}
|
|
6311
6723
|
};
|
|
6312
6724
|
|
|
6313
|
-
// src/core/types/baseUcan.ts
|
|
6314
|
-
function isRuntimeRef(value) {
|
|
6315
|
-
return typeof value === "object" && value !== null && "$ref" in value && typeof value.$ref === "string";
|
|
6316
|
-
}
|
|
6317
|
-
|
|
6318
6725
|
// src/core/lib/flowEngine/triggers.ts
|
|
6319
6726
|
import * as Y from "yjs";
|
|
6320
6727
|
var RUN_RECORD_AUDIT_TYPE = "block.run";
|
|
@@ -6323,15 +6730,15 @@ function computePendingInvocationId(args) {
|
|
|
6323
6730
|
const input = `${sourceBlockId}:${sourceRunId}:${listenerBlockId}:${eventName}:${eventIndex}`;
|
|
6324
6731
|
return `pi-${fnv1a32(input)}`;
|
|
6325
6732
|
}
|
|
6326
|
-
function snapshotInputRefs(inputs,
|
|
6733
|
+
function snapshotInputRefs(inputs, getNodeOutput2) {
|
|
6327
6734
|
const snapshots = {};
|
|
6328
6735
|
walkRefs(inputs, (ref) => {
|
|
6329
6736
|
if (ref.$ref.startsWith("trigger.")) return;
|
|
6330
6737
|
const parsed = parseOutputRef(ref.$ref);
|
|
6331
6738
|
if (!parsed) return;
|
|
6332
|
-
const output =
|
|
6739
|
+
const output = getNodeOutput2(parsed.nodeId);
|
|
6333
6740
|
if (!output) return;
|
|
6334
|
-
snapshots[ref.$ref] =
|
|
6741
|
+
snapshots[ref.$ref] = getNestedValue2(output, parsed.fieldPath);
|
|
6335
6742
|
});
|
|
6336
6743
|
return snapshots;
|
|
6337
6744
|
}
|
|
@@ -6356,7 +6763,7 @@ function parseOutputRef(ref) {
|
|
|
6356
6763
|
fieldPath: ref.slice(outputIndex + ".output.".length)
|
|
6357
6764
|
};
|
|
6358
6765
|
}
|
|
6359
|
-
function
|
|
6766
|
+
function getNestedValue2(obj, path) {
|
|
6360
6767
|
const parts = path.split(".");
|
|
6361
6768
|
let current = obj;
|
|
6362
6769
|
for (const part of parts) {
|
|
@@ -6584,7 +6991,7 @@ function _reconcilePendingInvocationsInner(editor) {
|
|
|
6584
6991
|
}
|
|
6585
6992
|
if (listenersBySource.size === 0 && barrierListenersBySource.size === 0) return;
|
|
6586
6993
|
const runtimeMap = editor._yRuntime;
|
|
6587
|
-
const
|
|
6994
|
+
const getNodeOutput2 = (nodeId) => {
|
|
6588
6995
|
if (!runtimeMap) return void 0;
|
|
6589
6996
|
const state = runtimeMap.get(nodeId);
|
|
6590
6997
|
if (!state || typeof state !== "object") return void 0;
|
|
@@ -6610,12 +7017,12 @@ function _reconcilePendingInvocationsInner(editor) {
|
|
|
6610
7017
|
if (!hasAnyListener) continue;
|
|
6611
7018
|
const records = readRunRecords(yDoc, sourceBlockId);
|
|
6612
7019
|
for (const record of records) {
|
|
6613
|
-
processRunRecord(yDoc, sourceBlockId, record, listenersBySource,
|
|
6614
|
-
processBarrierRunRecord(yDoc, sourceBlockId, record, barrierListenersBySource,
|
|
7020
|
+
processRunRecord(yDoc, sourceBlockId, record, listenersBySource, getNodeOutput2, runtimeMap);
|
|
7021
|
+
processBarrierRunRecord(yDoc, sourceBlockId, record, barrierListenersBySource, getNodeOutput2, runtimeMap);
|
|
6615
7022
|
}
|
|
6616
7023
|
}
|
|
6617
7024
|
}
|
|
6618
|
-
function processRunRecord(yDoc, sourceBlockId, record, listenersBySource,
|
|
7025
|
+
function processRunRecord(yDoc, sourceBlockId, record, listenersBySource, getNodeOutput2, runtimeMap) {
|
|
6619
7026
|
if (!Array.isArray(record.events)) return;
|
|
6620
7027
|
record.events.forEach((event, eventIndex) => {
|
|
6621
7028
|
if (!event?.name) return;
|
|
@@ -6634,7 +7041,7 @@ function processRunRecord(yDoc, sourceBlockId, record, listenersBySource, getNod
|
|
|
6634
7041
|
});
|
|
6635
7042
|
const assigneeDid = resolveAssignee(listenerBlock) || "unassigned";
|
|
6636
7043
|
const inputs = parseInputs(listenerBlock);
|
|
6637
|
-
const refSnapshots = snapshotInputRefs(inputs,
|
|
7044
|
+
const refSnapshots = snapshotInputRefs(inputs, getNodeOutput2);
|
|
6638
7045
|
const expiresAt = computeExpiry(listenerBlock, record.completedAt);
|
|
6639
7046
|
const invocation = {
|
|
6640
7047
|
id,
|
|
@@ -6659,7 +7066,7 @@ function processRunRecord(yDoc, sourceBlockId, record, listenersBySource, getNod
|
|
|
6659
7066
|
}
|
|
6660
7067
|
});
|
|
6661
7068
|
}
|
|
6662
|
-
function processBarrierRunRecord(yDoc, sourceBlockId, record, barrierListenersBySource,
|
|
7069
|
+
function processBarrierRunRecord(yDoc, sourceBlockId, record, barrierListenersBySource, getNodeOutput2, runtimeMap) {
|
|
6663
7070
|
if (!Array.isArray(record.events)) return;
|
|
6664
7071
|
for (const event of record.events) {
|
|
6665
7072
|
if (!event?.name) continue;
|
|
@@ -6694,7 +7101,7 @@ function processBarrierRunRecord(yDoc, sourceBlockId, record, barrierListenersBy
|
|
|
6694
7101
|
const id = computeBarrierInvocationId(currentState, listenerBlockId);
|
|
6695
7102
|
const mergedPayload = mergeBarrierPayloads(currentState);
|
|
6696
7103
|
const inputs = parseInputs(listenerBlock);
|
|
6697
|
-
const refSnapshots = snapshotInputRefs(inputs,
|
|
7104
|
+
const refSnapshots = snapshotInputRefs(inputs, getNodeOutput2);
|
|
6698
7105
|
const expiresAt = computeExpiry(listenerBlock, record.completedAt);
|
|
6699
7106
|
const invocation = {
|
|
6700
7107
|
id,
|
|
@@ -6804,6 +7211,553 @@ function writeRunRecordAndReconcile(editor, blockId, output, events, actorDid, d
|
|
|
6804
7211
|
reconcilePendingInvocations(editor);
|
|
6805
7212
|
}
|
|
6806
7213
|
|
|
7214
|
+
// src/core/lib/flowEngine/actionExecutor.ts
|
|
7215
|
+
import * as Y3 from "yjs";
|
|
7216
|
+
|
|
7217
|
+
// src/core/lib/flowEngine/readBackReconciler.ts
|
|
7218
|
+
import * as Y2 from "yjs";
|
|
7219
|
+
function isYDoc(value) {
|
|
7220
|
+
return value instanceof Y2.Doc;
|
|
7221
|
+
}
|
|
7222
|
+
function getYDoc(editorOrYDoc) {
|
|
7223
|
+
if (!editorOrYDoc) return void 0;
|
|
7224
|
+
if (isYDoc(editorOrYDoc)) return editorOrYDoc;
|
|
7225
|
+
return editorOrYDoc._yDoc;
|
|
7226
|
+
}
|
|
7227
|
+
function getEditor(editorOrYDoc) {
|
|
7228
|
+
return editorOrYDoc && !isYDoc(editorOrYDoc) ? editorOrYDoc : void 0;
|
|
7229
|
+
}
|
|
7230
|
+
function getRuntime(editorOrYDoc, runtime) {
|
|
7231
|
+
if (runtime) return runtime;
|
|
7232
|
+
const yDoc = getYDoc(editorOrYDoc);
|
|
7233
|
+
if (yDoc) return createYDocRuntimeManager(yDoc);
|
|
7234
|
+
return createRuntimeStateManager(!isYDoc(editorOrYDoc) ? editorOrYDoc : void 0);
|
|
7235
|
+
}
|
|
7236
|
+
function getReconcileEditor(params, yDoc, editor) {
|
|
7237
|
+
if (editor) return editor;
|
|
7238
|
+
if (!yDoc || !params.document) return void 0;
|
|
7239
|
+
return {
|
|
7240
|
+
_yDoc: yDoc,
|
|
7241
|
+
_yRuntime: yDoc.getMap("runtime"),
|
|
7242
|
+
document: params.document
|
|
7243
|
+
};
|
|
7244
|
+
}
|
|
7245
|
+
function makeRunId(now) {
|
|
7246
|
+
return `readback-${now()}-${Math.random().toString(36).slice(2, 8)}`;
|
|
7247
|
+
}
|
|
7248
|
+
function asOutput(value) {
|
|
7249
|
+
return value && typeof value === "object" && !Array.isArray(value) ? { ...value } : {};
|
|
7250
|
+
}
|
|
7251
|
+
function errorRecord(error) {
|
|
7252
|
+
if (!error) return void 0;
|
|
7253
|
+
return typeof error === "string" ? { message: error } : { message: error.message, code: error.code };
|
|
7254
|
+
}
|
|
7255
|
+
function normalizeActionReadBackMetadata(params) {
|
|
7256
|
+
const base = params.readBack && typeof params.readBack === "object" && !Array.isArray(params.readBack) ? { ...params.readBack } : {};
|
|
7257
|
+
const kind = typeof base.kind === "string" && base.kind.trim() ? base.kind.trim() : params.actionType;
|
|
7258
|
+
const normalized = {
|
|
7259
|
+
...base,
|
|
7260
|
+
kind,
|
|
7261
|
+
status: "pending",
|
|
7262
|
+
requestedAt: typeof base.requestedAt === "string" ? base.requestedAt : new Date(params.requestedAt).toISOString(),
|
|
7263
|
+
blockId: params.blockId,
|
|
7264
|
+
actionType: params.actionType,
|
|
7265
|
+
actorDid: params.actorDid,
|
|
7266
|
+
invocationCid: params.invocationCid,
|
|
7267
|
+
capabilityId: params.capabilityId
|
|
7268
|
+
};
|
|
7269
|
+
if (params.pendingInvocation) {
|
|
7270
|
+
normalized.pendingInvocation = {
|
|
7271
|
+
id: params.pendingInvocation.id,
|
|
7272
|
+
triggeringBlockId: params.pendingInvocation.triggeringBlockId,
|
|
7273
|
+
eventName: params.pendingInvocation.eventName,
|
|
7274
|
+
sourceRunId: params.pendingInvocation.sourceRunId
|
|
7275
|
+
};
|
|
7276
|
+
}
|
|
7277
|
+
return normalized;
|
|
7278
|
+
}
|
|
7279
|
+
function writeReconciliationRunRecord(params) {
|
|
7280
|
+
if (!params.yDoc) return void 0;
|
|
7281
|
+
const completedAt = params.now();
|
|
7282
|
+
const runId = makeRunId(params.now);
|
|
7283
|
+
const pendingInvocation = params.readBack.pendingInvocation;
|
|
7284
|
+
const details = {
|
|
7285
|
+
runId,
|
|
7286
|
+
output: params.output,
|
|
7287
|
+
events: params.events,
|
|
7288
|
+
startedAt: params.readBack.requestedAt || new Date(completedAt).toISOString(),
|
|
7289
|
+
completedAt: new Date(completedAt).toISOString(),
|
|
7290
|
+
actorDid: params.actorDid,
|
|
7291
|
+
invocationCid: params.readBack.invocationCid,
|
|
7292
|
+
capabilityId: params.readBack.capabilityId,
|
|
7293
|
+
error: params.error,
|
|
7294
|
+
readBack: params.readBack,
|
|
7295
|
+
reconciled: true
|
|
7296
|
+
};
|
|
7297
|
+
if (pendingInvocation) {
|
|
7298
|
+
details.fromPendingInvocationId = pendingInvocation.id;
|
|
7299
|
+
details.triggeredBy = {
|
|
7300
|
+
sourceBlockId: pendingInvocation.triggeringBlockId,
|
|
7301
|
+
eventName: pendingInvocation.eventName
|
|
7302
|
+
};
|
|
7303
|
+
details.sourceRunId = pendingInvocation.sourceRunId;
|
|
7304
|
+
}
|
|
7305
|
+
appendRunRecord(params.yDoc, params.blockId, details, params.actorDid);
|
|
7306
|
+
if (params.editor && params.events.length > 0) {
|
|
7307
|
+
reconcilePendingInvocations(params.editor);
|
|
7308
|
+
}
|
|
7309
|
+
return runId;
|
|
7310
|
+
}
|
|
7311
|
+
async function reconcileActionReadBack(params) {
|
|
7312
|
+
const now = params.now || Date.now;
|
|
7313
|
+
const yDoc = getYDoc(params.editorOrYDoc);
|
|
7314
|
+
const editor = getEditor(params.editorOrYDoc);
|
|
7315
|
+
const runtime = getRuntime(params.editorOrYDoc, params.runtime);
|
|
7316
|
+
const current = runtime.get(params.blockId);
|
|
7317
|
+
const output = asOutput(current.output);
|
|
7318
|
+
const readBack = current.readBack;
|
|
7319
|
+
if (current.state !== "awaiting_readback" || !readBack?.kind) {
|
|
7320
|
+
return {
|
|
7321
|
+
success: false,
|
|
7322
|
+
blockId: params.blockId,
|
|
7323
|
+
state: current.state === "failed" ? "failed" : "pending",
|
|
7324
|
+
output,
|
|
7325
|
+
events: [],
|
|
7326
|
+
error: `Block "${params.blockId}" is not awaiting read-back`,
|
|
7327
|
+
pendingInvocationRemoved: false,
|
|
7328
|
+
readBack
|
|
7329
|
+
};
|
|
7330
|
+
}
|
|
7331
|
+
const resolver = params.resolver || params.resolvers?.[readBack.kind];
|
|
7332
|
+
if (!resolver) {
|
|
7333
|
+
return {
|
|
7334
|
+
success: false,
|
|
7335
|
+
blockId: params.blockId,
|
|
7336
|
+
state: "pending",
|
|
7337
|
+
output,
|
|
7338
|
+
events: [],
|
|
7339
|
+
error: `No read-back resolver registered for "${readBack.kind}"`,
|
|
7340
|
+
pendingInvocationRemoved: false,
|
|
7341
|
+
readBack
|
|
7342
|
+
};
|
|
7343
|
+
}
|
|
7344
|
+
const resolution = await resolver({
|
|
7345
|
+
blockId: params.blockId,
|
|
7346
|
+
runtime: current,
|
|
7347
|
+
output,
|
|
7348
|
+
readBack
|
|
7349
|
+
});
|
|
7350
|
+
const checkedAt = now();
|
|
7351
|
+
const checkedIso = new Date(checkedAt).toISOString();
|
|
7352
|
+
const nextReadBack = {
|
|
7353
|
+
...readBack,
|
|
7354
|
+
...resolution.readBack || {},
|
|
7355
|
+
status: resolution.state,
|
|
7356
|
+
lastCheckedAt: checkedIso
|
|
7357
|
+
};
|
|
7358
|
+
if (resolution.state === "pending") {
|
|
7359
|
+
runtime.update(params.blockId, {
|
|
7360
|
+
readBack: nextReadBack
|
|
7361
|
+
});
|
|
7362
|
+
return {
|
|
7363
|
+
success: true,
|
|
7364
|
+
blockId: params.blockId,
|
|
7365
|
+
state: "pending",
|
|
7366
|
+
output,
|
|
7367
|
+
events: resolution.events || [],
|
|
7368
|
+
pendingInvocationRemoved: false,
|
|
7369
|
+
readBack: nextReadBack
|
|
7370
|
+
};
|
|
7371
|
+
}
|
|
7372
|
+
const events = resolution.events || [];
|
|
7373
|
+
const finalOutput = {
|
|
7374
|
+
...output,
|
|
7375
|
+
...resolution.output || {}
|
|
7376
|
+
};
|
|
7377
|
+
const actorDid = params.actorDid || readBack.actorDid || current.executedByDid || "system:readback";
|
|
7378
|
+
if (resolution.state === "failed") {
|
|
7379
|
+
const error = errorRecord(resolution.error) || { message: "External read-back failed" };
|
|
7380
|
+
const failedReadBack = {
|
|
7381
|
+
...nextReadBack,
|
|
7382
|
+
terminalAt: checkedIso
|
|
7383
|
+
};
|
|
7384
|
+
runtime.update(params.blockId, {
|
|
7385
|
+
state: "failed",
|
|
7386
|
+
output: finalOutput,
|
|
7387
|
+
error: { ...error, at: checkedAt },
|
|
7388
|
+
readBack: failedReadBack
|
|
7389
|
+
});
|
|
7390
|
+
const runId2 = writeReconciliationRunRecord({
|
|
7391
|
+
yDoc,
|
|
7392
|
+
editor: getReconcileEditor(params, yDoc, editor),
|
|
7393
|
+
blockId: params.blockId,
|
|
7394
|
+
actorDid,
|
|
7395
|
+
output: finalOutput,
|
|
7396
|
+
events,
|
|
7397
|
+
readBack: failedReadBack,
|
|
7398
|
+
error,
|
|
7399
|
+
now
|
|
7400
|
+
});
|
|
7401
|
+
return {
|
|
7402
|
+
success: false,
|
|
7403
|
+
blockId: params.blockId,
|
|
7404
|
+
state: "failed",
|
|
7405
|
+
output: finalOutput,
|
|
7406
|
+
events,
|
|
7407
|
+
error: error.message,
|
|
7408
|
+
runId: runId2,
|
|
7409
|
+
pendingInvocationRemoved: false,
|
|
7410
|
+
readBack: failedReadBack
|
|
7411
|
+
};
|
|
7412
|
+
}
|
|
7413
|
+
const completedReadBack = {
|
|
7414
|
+
...nextReadBack,
|
|
7415
|
+
terminalAt: checkedIso
|
|
7416
|
+
};
|
|
7417
|
+
runtime.update(params.blockId, {
|
|
7418
|
+
state: "completed",
|
|
7419
|
+
output: finalOutput,
|
|
7420
|
+
executedAt: checkedAt,
|
|
7421
|
+
error: void 0,
|
|
7422
|
+
readBack: completedReadBack
|
|
7423
|
+
});
|
|
7424
|
+
const runId = writeReconciliationRunRecord({
|
|
7425
|
+
yDoc,
|
|
7426
|
+
editor: getReconcileEditor(params, yDoc, editor),
|
|
7427
|
+
blockId: params.blockId,
|
|
7428
|
+
actorDid,
|
|
7429
|
+
output: finalOutput,
|
|
7430
|
+
events,
|
|
7431
|
+
readBack: completedReadBack,
|
|
7432
|
+
now
|
|
7433
|
+
});
|
|
7434
|
+
const pendingInvocationRemoved = Boolean(yDoc && completedReadBack.pendingInvocation?.id) && removePendingInvocation(yDoc, params.blockId, completedReadBack.pendingInvocation.id);
|
|
7435
|
+
return {
|
|
7436
|
+
success: true,
|
|
7437
|
+
blockId: params.blockId,
|
|
7438
|
+
state: "completed",
|
|
7439
|
+
output: finalOutput,
|
|
7440
|
+
events,
|
|
7441
|
+
runId,
|
|
7442
|
+
pendingInvocationRemoved,
|
|
7443
|
+
readBack: completedReadBack
|
|
7444
|
+
};
|
|
7445
|
+
}
|
|
7446
|
+
|
|
7447
|
+
// src/core/lib/flowEngine/actionExecutor.ts
|
|
7448
|
+
function isYDoc2(value) {
|
|
7449
|
+
return value instanceof Y3.Doc;
|
|
7450
|
+
}
|
|
7451
|
+
function getYDoc2(editorOrYDoc) {
|
|
7452
|
+
if (!editorOrYDoc) return void 0;
|
|
7453
|
+
if (isYDoc2(editorOrYDoc)) return editorOrYDoc;
|
|
7454
|
+
return editorOrYDoc._yDoc;
|
|
7455
|
+
}
|
|
7456
|
+
function parseInputs2(value) {
|
|
7457
|
+
if (value == null || value === "") return {};
|
|
7458
|
+
if (typeof value === "object" && !Array.isArray(value)) return { ...value };
|
|
7459
|
+
if (typeof value !== "string") return {};
|
|
7460
|
+
try {
|
|
7461
|
+
const parsed = JSON.parse(value);
|
|
7462
|
+
return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : {};
|
|
7463
|
+
} catch {
|
|
7464
|
+
return {};
|
|
7465
|
+
}
|
|
7466
|
+
}
|
|
7467
|
+
function getRuntime2(editorOrYDoc, runtime) {
|
|
7468
|
+
if (runtime) return runtime;
|
|
7469
|
+
const yDoc = getYDoc2(editorOrYDoc);
|
|
7470
|
+
if (yDoc) return createYDocRuntimeManager(yDoc);
|
|
7471
|
+
return createRuntimeStateManager(!isYDoc2(editorOrYDoc) ? editorOrYDoc : void 0);
|
|
7472
|
+
}
|
|
7473
|
+
function getEditor2(editorOrYDoc) {
|
|
7474
|
+
return editorOrYDoc && !isYDoc2(editorOrYDoc) ? editorOrYDoc : void 0;
|
|
7475
|
+
}
|
|
7476
|
+
function findBlock(params) {
|
|
7477
|
+
if (params.block) return params.block;
|
|
7478
|
+
const blockId = params.blockId;
|
|
7479
|
+
if (!blockId) return void 0;
|
|
7480
|
+
const editor = getEditor2(params.editorOrYDoc);
|
|
7481
|
+
return (params.document || editor?.document || []).find((block) => block?.id === blockId);
|
|
7482
|
+
}
|
|
7483
|
+
function getFlowMetadata(editor) {
|
|
7484
|
+
const metadata = editor?.getFlowMetadata?.();
|
|
7485
|
+
const flowId = metadata?.doc_id || "";
|
|
7486
|
+
return {
|
|
7487
|
+
flowId,
|
|
7488
|
+
flowUri: flowId ? `ixo:flow:${flowId}` : "",
|
|
7489
|
+
flowOwnerDid: editor?.getFlowOwnerDid?.() || metadata?.flowOwnerDid || "",
|
|
7490
|
+
schemaVersion: metadata?.schema_version || "0.3"
|
|
7491
|
+
};
|
|
7492
|
+
}
|
|
7493
|
+
function getPendingInvocation(yDoc, blockId, pendingInvocationId) {
|
|
7494
|
+
if (!pendingInvocationId) return void 0;
|
|
7495
|
+
if (!yDoc) {
|
|
7496
|
+
throw new Error(`Cannot load pending invocation "${pendingInvocationId}" without a Y.Doc`);
|
|
7497
|
+
}
|
|
7498
|
+
if (!blockId) {
|
|
7499
|
+
throw new Error(`Cannot load pending invocation "${pendingInvocationId}" without a block id`);
|
|
7500
|
+
}
|
|
7501
|
+
const pending = readPendingInvocations(yDoc, blockId).find((invocation) => invocation.id === pendingInvocationId);
|
|
7502
|
+
if (!pending) {
|
|
7503
|
+
throw new Error(`Pending invocation "${pendingInvocationId}" was not found for block "${blockId}"`);
|
|
7504
|
+
}
|
|
7505
|
+
return pending;
|
|
7506
|
+
}
|
|
7507
|
+
function getNodeOutput(runtime, nodeId) {
|
|
7508
|
+
const state = runtime.get(nodeId);
|
|
7509
|
+
const output = state.output;
|
|
7510
|
+
return output && typeof output === "object" && !Array.isArray(output) ? output : void 0;
|
|
7511
|
+
}
|
|
7512
|
+
function buildActionRunInputs(params) {
|
|
7513
|
+
const blockId = params.blockId || params.block?.id;
|
|
7514
|
+
const yDoc = getYDoc2(params.editorOrYDoc);
|
|
7515
|
+
const runtime = getRuntime2(params.editorOrYDoc, params.runtime);
|
|
7516
|
+
const savedInputs = parseInputs2(params.savedInputs ?? params.block?.props?.inputs);
|
|
7517
|
+
const pendingInvocation = getPendingInvocation(yDoc, blockId, params.pendingInvocationId);
|
|
7518
|
+
const triggerContext = pendingInvocation ? {
|
|
7519
|
+
payload: pendingInvocation.payload || {},
|
|
7520
|
+
refSnapshots: pendingInvocation.refSnapshots || {}
|
|
7521
|
+
} : void 0;
|
|
7522
|
+
const mergedInputs = {
|
|
7523
|
+
...savedInputs,
|
|
7524
|
+
...pendingInvocation?.payload || {},
|
|
7525
|
+
...pendingInvocation?.refSnapshots || {},
|
|
7526
|
+
...params.runtimeInputs || {}
|
|
7527
|
+
};
|
|
7528
|
+
return {
|
|
7529
|
+
inputs: resolveRuntimeRefs(mergedInputs, (nodeId) => getNodeOutput(runtime, nodeId), triggerContext),
|
|
7530
|
+
savedInputs,
|
|
7531
|
+
mergedInputs,
|
|
7532
|
+
pendingInvocation,
|
|
7533
|
+
triggerContext
|
|
7534
|
+
};
|
|
7535
|
+
}
|
|
7536
|
+
function buildFailureResult(params) {
|
|
7537
|
+
return {
|
|
7538
|
+
success: false,
|
|
7539
|
+
stage: params.stage,
|
|
7540
|
+
blockId: params.blockId,
|
|
7541
|
+
actionType: params.actionType,
|
|
7542
|
+
events: [],
|
|
7543
|
+
error: params.error,
|
|
7544
|
+
completionState: "failed",
|
|
7545
|
+
pendingInvocation: params.pendingInvocation
|
|
7546
|
+
};
|
|
7547
|
+
}
|
|
7548
|
+
function updateRuntimeFailure(runtime, blockId, message, now) {
|
|
7549
|
+
runtime.update(blockId, {
|
|
7550
|
+
state: "failed",
|
|
7551
|
+
error: { message, at: now() }
|
|
7552
|
+
});
|
|
7553
|
+
}
|
|
7554
|
+
function makeRunId2(now) {
|
|
7555
|
+
return `run-${now()}-${Math.random().toString(36).slice(2, 8)}`;
|
|
7556
|
+
}
|
|
7557
|
+
function getReconcileEditor2(params, yDoc, editor) {
|
|
7558
|
+
if (editor) return editor;
|
|
7559
|
+
if (!yDoc || !params.document) return void 0;
|
|
7560
|
+
return {
|
|
7561
|
+
_yDoc: yDoc,
|
|
7562
|
+
_yRuntime: yDoc.getMap("runtime"),
|
|
7563
|
+
document: params.document
|
|
7564
|
+
};
|
|
7565
|
+
}
|
|
7566
|
+
function persistEvents(params) {
|
|
7567
|
+
if (!params.yDoc || params.events.length === 0) return void 0;
|
|
7568
|
+
const runId = makeRunId2(params.now);
|
|
7569
|
+
const details = {
|
|
7570
|
+
runId,
|
|
7571
|
+
output: params.output,
|
|
7572
|
+
events: params.events,
|
|
7573
|
+
startedAt: new Date(params.startedAt).toISOString(),
|
|
7574
|
+
completedAt: new Date(params.completedAt).toISOString(),
|
|
7575
|
+
actorDid: params.actorDid,
|
|
7576
|
+
invocationCid: params.invocationCid,
|
|
7577
|
+
capabilityId: params.capabilityId
|
|
7578
|
+
};
|
|
7579
|
+
if (params.pendingInvocation) {
|
|
7580
|
+
details.fromPendingInvocationId = params.pendingInvocation.id;
|
|
7581
|
+
details.triggeredBy = {
|
|
7582
|
+
sourceBlockId: params.pendingInvocation.triggeringBlockId,
|
|
7583
|
+
eventName: params.pendingInvocation.eventName
|
|
7584
|
+
};
|
|
7585
|
+
details.sourceRunId = params.pendingInvocation.sourceRunId;
|
|
7586
|
+
}
|
|
7587
|
+
appendRunRecord(params.yDoc, params.blockId, details, params.actorDid);
|
|
7588
|
+
if (params.editor) {
|
|
7589
|
+
reconcilePendingInvocations(params.editor);
|
|
7590
|
+
}
|
|
7591
|
+
return runId;
|
|
7592
|
+
}
|
|
7593
|
+
function cleanupCompletedPendingInvocation(yDoc, blockId, pendingInvocation) {
|
|
7594
|
+
if (!yDoc || !pendingInvocation) return false;
|
|
7595
|
+
return removePendingInvocation(yDoc, blockId, pendingInvocation.id);
|
|
7596
|
+
}
|
|
7597
|
+
async function executeActionBlock(params) {
|
|
7598
|
+
const block = findBlock(params);
|
|
7599
|
+
const blockId = params.blockId || block?.id;
|
|
7600
|
+
const editor = getEditor2(params.editorOrYDoc);
|
|
7601
|
+
const yDoc = getYDoc2(params.editorOrYDoc);
|
|
7602
|
+
const runtime = getRuntime2(params.editorOrYDoc, params.runtime);
|
|
7603
|
+
const now = params.now || Date.now;
|
|
7604
|
+
if (!block || !blockId) {
|
|
7605
|
+
return buildFailureResult({
|
|
7606
|
+
blockId: blockId || "",
|
|
7607
|
+
stage: "input",
|
|
7608
|
+
error: blockId ? `Block "${blockId}" was not found` : "executeActionBlock requires a blockId or block"
|
|
7609
|
+
});
|
|
7610
|
+
}
|
|
7611
|
+
const actionType = typeof block.props?.actionType === "string" ? block.props.actionType : void 0;
|
|
7612
|
+
if (!actionType) {
|
|
7613
|
+
updateRuntimeFailure(runtime, blockId, "Action block is missing props.actionType", now);
|
|
7614
|
+
return buildFailureResult({
|
|
7615
|
+
blockId,
|
|
7616
|
+
stage: "input",
|
|
7617
|
+
error: "Action block is missing props.actionType"
|
|
7618
|
+
});
|
|
7619
|
+
}
|
|
7620
|
+
const action = getAction(actionType);
|
|
7621
|
+
if (!action) {
|
|
7622
|
+
const message = `No registered action found for ${actionType}`;
|
|
7623
|
+
updateRuntimeFailure(runtime, blockId, message, now);
|
|
7624
|
+
return buildFailureResult({ blockId, actionType, stage: "action_lookup", error: message });
|
|
7625
|
+
}
|
|
7626
|
+
let inputBuild;
|
|
7627
|
+
try {
|
|
7628
|
+
inputBuild = buildActionRunInputs({ ...params, block, blockId, runtime });
|
|
7629
|
+
} catch (error) {
|
|
7630
|
+
const message = error instanceof Error ? error.message : "Failed to build action inputs";
|
|
7631
|
+
updateRuntimeFailure(runtime, blockId, message, now);
|
|
7632
|
+
return buildFailureResult({ blockId, actionType, stage: "input", error: message });
|
|
7633
|
+
}
|
|
7634
|
+
const flowNode = buildFlowNodeFromBlock(block);
|
|
7635
|
+
const metadata = getFlowMetadata(editor);
|
|
7636
|
+
const flowId = params.flowId || metadata.flowId || blockId;
|
|
7637
|
+
const flowUri = params.flowUri || metadata.flowUri || `ixo:flow:${flowId}`;
|
|
7638
|
+
const flowOwnerDid = params.flowOwnerDid || metadata.flowOwnerDid;
|
|
7639
|
+
const schemaVersion = params.schemaVersion || metadata.schemaVersion;
|
|
7640
|
+
const events = [];
|
|
7641
|
+
let completionState = "completed";
|
|
7642
|
+
let readBack;
|
|
7643
|
+
let rawReadBack;
|
|
7644
|
+
let requestedAwaitingReadBack = false;
|
|
7645
|
+
const startedAt = now();
|
|
7646
|
+
runtime.update(blockId, {
|
|
7647
|
+
state: "running",
|
|
7648
|
+
output: void 0,
|
|
7649
|
+
error: void 0,
|
|
7650
|
+
executedByDid: params.actorDid
|
|
7651
|
+
});
|
|
7652
|
+
const outcome = await executeNode({
|
|
7653
|
+
node: flowNode,
|
|
7654
|
+
actorDid: params.actorDid,
|
|
7655
|
+
actorType: params.actorType,
|
|
7656
|
+
entityRoomId: params.entityRoomId,
|
|
7657
|
+
context: {
|
|
7658
|
+
runtime,
|
|
7659
|
+
ucanService: params.ucanService || editor?.getUcanService?.() || void 0,
|
|
7660
|
+
invocationStore: params.invocationStore || editor?._invocationStore,
|
|
7661
|
+
flowUri,
|
|
7662
|
+
flowId,
|
|
7663
|
+
flowOwnerDid,
|
|
7664
|
+
schemaVersion,
|
|
7665
|
+
now
|
|
7666
|
+
},
|
|
7667
|
+
action: async () => {
|
|
7668
|
+
const result = await action.run(inputBuild.inputs, {
|
|
7669
|
+
actorDid: params.actorDid,
|
|
7670
|
+
flowId,
|
|
7671
|
+
flowUri,
|
|
7672
|
+
nodeId: blockId,
|
|
7673
|
+
flowNode,
|
|
7674
|
+
runtime,
|
|
7675
|
+
services: params.services || {},
|
|
7676
|
+
handlers: params.handlers,
|
|
7677
|
+
editor,
|
|
7678
|
+
pendingInvocation: inputBuild.pendingInvocation
|
|
7679
|
+
});
|
|
7680
|
+
if (result.events?.length) events.push(...result.events);
|
|
7681
|
+
if (result.completion?.state === "awaiting_readback") {
|
|
7682
|
+
requestedAwaitingReadBack = true;
|
|
7683
|
+
rawReadBack = result.completion.readBack;
|
|
7684
|
+
}
|
|
7685
|
+
return {
|
|
7686
|
+
payload: result.output,
|
|
7687
|
+
submittedByDid: params.actorDid || void 0
|
|
7688
|
+
};
|
|
7689
|
+
},
|
|
7690
|
+
pin: params.pin || ""
|
|
7691
|
+
});
|
|
7692
|
+
if (!outcome.success) {
|
|
7693
|
+
const message = outcome.error || "Action execution failed";
|
|
7694
|
+
updateRuntimeFailure(runtime, blockId, message, now);
|
|
7695
|
+
return {
|
|
7696
|
+
...buildFailureResult({
|
|
7697
|
+
blockId,
|
|
7698
|
+
actionType,
|
|
7699
|
+
stage: outcome.stage,
|
|
7700
|
+
error: message,
|
|
7701
|
+
pendingInvocation: inputBuild.pendingInvocation
|
|
7702
|
+
}),
|
|
7703
|
+
invocationCid: outcome.invocationCid,
|
|
7704
|
+
capabilityId: outcome.capabilityId
|
|
7705
|
+
};
|
|
7706
|
+
}
|
|
7707
|
+
const output = outcome.result?.payload || {};
|
|
7708
|
+
const completedAt = now();
|
|
7709
|
+
if (requestedAwaitingReadBack) {
|
|
7710
|
+
completionState = "awaiting_readback";
|
|
7711
|
+
readBack = normalizeActionReadBackMetadata({
|
|
7712
|
+
readBack: rawReadBack,
|
|
7713
|
+
blockId,
|
|
7714
|
+
actionType,
|
|
7715
|
+
actorDid: params.actorDid,
|
|
7716
|
+
invocationCid: outcome.invocationCid,
|
|
7717
|
+
capabilityId: outcome.capabilityId,
|
|
7718
|
+
requestedAt: startedAt,
|
|
7719
|
+
pendingInvocation: inputBuild.pendingInvocation
|
|
7720
|
+
});
|
|
7721
|
+
}
|
|
7722
|
+
runtime.update(blockId, {
|
|
7723
|
+
state: completionState,
|
|
7724
|
+
output,
|
|
7725
|
+
executedByDid: params.actorDid,
|
|
7726
|
+
executedAt: completedAt,
|
|
7727
|
+
lastInvocationCid: outcome.invocationCid || outcome.capabilityId,
|
|
7728
|
+
readBack
|
|
7729
|
+
});
|
|
7730
|
+
const runId = persistEvents({
|
|
7731
|
+
yDoc,
|
|
7732
|
+
editor: getReconcileEditor2(params, yDoc, editor),
|
|
7733
|
+
blockId,
|
|
7734
|
+
actorDid: params.actorDid,
|
|
7735
|
+
output,
|
|
7736
|
+
events,
|
|
7737
|
+
invocationCid: outcome.invocationCid,
|
|
7738
|
+
capabilityId: outcome.capabilityId,
|
|
7739
|
+
pendingInvocation: inputBuild.pendingInvocation,
|
|
7740
|
+
startedAt,
|
|
7741
|
+
completedAt,
|
|
7742
|
+
now
|
|
7743
|
+
});
|
|
7744
|
+
const pendingInvocationRemoved = completionState === "completed" ? cleanupCompletedPendingInvocation(yDoc, blockId, inputBuild.pendingInvocation) : false;
|
|
7745
|
+
return {
|
|
7746
|
+
success: true,
|
|
7747
|
+
stage: outcome.stage,
|
|
7748
|
+
blockId,
|
|
7749
|
+
actionType,
|
|
7750
|
+
output,
|
|
7751
|
+
events,
|
|
7752
|
+
invocationCid: outcome.invocationCid,
|
|
7753
|
+
capabilityId: outcome.capabilityId,
|
|
7754
|
+
runId,
|
|
7755
|
+
pendingInvocationRemoved,
|
|
7756
|
+
completionState,
|
|
7757
|
+
pendingInvocation: inputBuild.pendingInvocation
|
|
7758
|
+
};
|
|
7759
|
+
}
|
|
7760
|
+
|
|
6807
7761
|
// src/core/lib/flowEngine/migration.ts
|
|
6808
7762
|
var MIGRATION_REGISTRY = {};
|
|
6809
7763
|
function registerMigration(definition) {
|
|
@@ -7251,13 +8205,13 @@ function detectTriggerCycles(triggerEdges) {
|
|
|
7251
8205
|
}
|
|
7252
8206
|
|
|
7253
8207
|
// src/core/lib/flowCompiler/readFlow.ts
|
|
7254
|
-
import * as
|
|
8208
|
+
import * as Y4 from "yjs";
|
|
7255
8209
|
function readCompiledFlowFromYDoc(yDoc) {
|
|
7256
8210
|
const flowMeta = yDoc.getMap("qi.flow.meta");
|
|
7257
8211
|
const flowNodes = yDoc.getMap("qi.flow.nodes");
|
|
7258
8212
|
const nodes = {};
|
|
7259
8213
|
flowNodes.forEach((value, nodeId) => {
|
|
7260
|
-
if (value instanceof
|
|
8214
|
+
if (value instanceof Y4.Map) {
|
|
7261
8215
|
nodes[nodeId] = yMapToFlowNode(value);
|
|
7262
8216
|
}
|
|
7263
8217
|
});
|
|
@@ -7277,7 +8231,7 @@ function readCompiledFlowFromYDoc(yDoc) {
|
|
|
7277
8231
|
const flowEdges = yDoc.getMap("qi.flow.edges");
|
|
7278
8232
|
const edges = [];
|
|
7279
8233
|
flowEdges.forEach((value) => {
|
|
7280
|
-
if (value instanceof
|
|
8234
|
+
if (value instanceof Y4.Map) {
|
|
7281
8235
|
edges.push(yMapToEdge(value));
|
|
7282
8236
|
}
|
|
7283
8237
|
});
|
|
@@ -7458,11 +8412,11 @@ function nodeToCapability(node) {
|
|
|
7458
8412
|
}
|
|
7459
8413
|
|
|
7460
8414
|
// src/core/lib/flowCompiler/setup.ts
|
|
7461
|
-
import * as
|
|
8415
|
+
import * as Y7 from "yjs";
|
|
7462
8416
|
import { MatrixProvider } from "@ixo/matrix-crdt";
|
|
7463
8417
|
|
|
7464
8418
|
// src/core/lib/flowCompiler/hydrate.ts
|
|
7465
|
-
import * as
|
|
8419
|
+
import * as Y5 from "yjs";
|
|
7466
8420
|
function hydrateYDocFromCompiledFlow(yDoc, compiled) {
|
|
7467
8421
|
yDoc.transact(() => {
|
|
7468
8422
|
const flowMeta = yDoc.getMap("qi.flow.meta");
|
|
@@ -7477,7 +8431,7 @@ function hydrateYDocFromCompiledFlow(yDoc, compiled) {
|
|
|
7477
8431
|
}
|
|
7478
8432
|
const flowEdges = yDoc.getMap("qi.flow.edges");
|
|
7479
8433
|
for (const edge of compiled.edges) {
|
|
7480
|
-
const yEdge = new
|
|
8434
|
+
const yEdge = new Y5.Map();
|
|
7481
8435
|
yEdge.set("id", edge.id);
|
|
7482
8436
|
yEdge.set("source", edge.source);
|
|
7483
8437
|
yEdge.set("target", edge.target);
|
|
@@ -7531,7 +8485,7 @@ function hydrateYDocFromMergeResult(yDoc, mergeResult) {
|
|
|
7531
8485
|
const flowEdges = yDoc.getMap("qi.flow.edges");
|
|
7532
8486
|
flowEdges.forEach((_, key) => flowEdges.delete(key));
|
|
7533
8487
|
for (const edge of merged.edges) {
|
|
7534
|
-
const yEdge = new
|
|
8488
|
+
const yEdge = new Y5.Map();
|
|
7535
8489
|
yEdge.set("id", edge.id);
|
|
7536
8490
|
yEdge.set("source", edge.source);
|
|
7537
8491
|
yEdge.set("target", edge.target);
|
|
@@ -7566,7 +8520,7 @@ function initializeRuntimeForNodes(runtimeMap, compiled, nodeIds) {
|
|
|
7566
8520
|
}
|
|
7567
8521
|
}
|
|
7568
8522
|
function createYMapFromNode(node) {
|
|
7569
|
-
const yNode = new
|
|
8523
|
+
const yNode = new Y5.Map();
|
|
7570
8524
|
yNode.set("id", node.id);
|
|
7571
8525
|
yNode.set("blockId", node.blockId);
|
|
7572
8526
|
yNode.set("can", node.can);
|
|
@@ -7581,7 +8535,7 @@ function createYMapFromNode(node) {
|
|
|
7581
8535
|
}
|
|
7582
8536
|
|
|
7583
8537
|
// src/core/lib/flowCompiler/documentFragment.ts
|
|
7584
|
-
import * as
|
|
8538
|
+
import * as Y6 from "yjs";
|
|
7585
8539
|
function writeCompiledBlocksToFragment(fragment, blocks) {
|
|
7586
8540
|
const documentBlockGroup = getOrCreateDocumentBlockGroup(fragment);
|
|
7587
8541
|
for (const block of blocks) {
|
|
@@ -7600,7 +8554,7 @@ function replaceBlockInFragment(fragment, block) {
|
|
|
7600
8554
|
if (!blockGroup) return false;
|
|
7601
8555
|
for (let i = 0; i < blockGroup.length; i++) {
|
|
7602
8556
|
const container = blockGroup.get(i);
|
|
7603
|
-
if (container instanceof
|
|
8557
|
+
if (container instanceof Y6.XmlElement && container.getAttribute("id") === block.id) {
|
|
7604
8558
|
blockGroup.delete(i, 1);
|
|
7605
8559
|
const newContainer = createBlockContainer(block);
|
|
7606
8560
|
blockGroup.insert(i, [newContainer]);
|
|
@@ -7634,12 +8588,12 @@ function applyMergeResultToFragment(fragment, mergeResult) {
|
|
|
7634
8588
|
}
|
|
7635
8589
|
}
|
|
7636
8590
|
function createBlockContainer(block) {
|
|
7637
|
-
const blockContainer = new
|
|
8591
|
+
const blockContainer = new Y6.XmlElement("blockContainer");
|
|
7638
8592
|
const { backgroundColor: rawBackgroundColor, textColor: rawTextColor, ...contentProps } = block.props;
|
|
7639
8593
|
blockContainer.setAttribute("id", block.id);
|
|
7640
8594
|
blockContainer.setAttribute("textColor", rawTextColor || "default");
|
|
7641
8595
|
blockContainer.setAttribute("backgroundColor", rawBackgroundColor || "default");
|
|
7642
|
-
const blockContent = new
|
|
8596
|
+
const blockContent = new Y6.XmlElement(block.type);
|
|
7643
8597
|
for (const [key, value] of Object.entries(contentProps)) {
|
|
7644
8598
|
if (value !== "") {
|
|
7645
8599
|
blockContent.setAttribute(key, value);
|
|
@@ -7654,13 +8608,13 @@ function appendBlockToGroup(blockGroup, block) {
|
|
|
7654
8608
|
}
|
|
7655
8609
|
function getOrCreateDocumentBlockGroup(fragment) {
|
|
7656
8610
|
if (fragment.length === 0) {
|
|
7657
|
-
const blockGroup = new
|
|
8611
|
+
const blockGroup = new Y6.XmlElement("blockGroup");
|
|
7658
8612
|
fragment.insert(0, [blockGroup]);
|
|
7659
8613
|
return blockGroup;
|
|
7660
8614
|
}
|
|
7661
8615
|
if (fragment.length === 1) {
|
|
7662
8616
|
const rootNode = fragment.get(0);
|
|
7663
|
-
if (rootNode instanceof
|
|
8617
|
+
if (rootNode instanceof Y6.XmlElement && rootNode.nodeName === "blockGroup") {
|
|
7664
8618
|
return rootNode;
|
|
7665
8619
|
}
|
|
7666
8620
|
}
|
|
@@ -7670,7 +8624,7 @@ function getExistingBlockGroup(fragment) {
|
|
|
7670
8624
|
if (fragment.length === 0) return null;
|
|
7671
8625
|
if (fragment.length === 1) {
|
|
7672
8626
|
const rootNode = fragment.get(0);
|
|
7673
|
-
if (rootNode instanceof
|
|
8627
|
+
if (rootNode instanceof Y6.XmlElement && rootNode.nodeName === "blockGroup") {
|
|
7674
8628
|
return rootNode;
|
|
7675
8629
|
}
|
|
7676
8630
|
}
|
|
@@ -7773,7 +8727,7 @@ async function setupFlowFromBaseUcan(options) {
|
|
|
7773
8727
|
};
|
|
7774
8728
|
}
|
|
7775
8729
|
async function connectToRoom(roomId, matrixClient) {
|
|
7776
|
-
const yDoc = new
|
|
8730
|
+
const yDoc = new Y7.Doc();
|
|
7777
8731
|
const client = matrixClient;
|
|
7778
8732
|
client.canSupportVoip = false;
|
|
7779
8733
|
client.clientOpts = { lazyLoadMembers: true };
|
|
@@ -7828,7 +8782,7 @@ function setRootMetadata(yDoc, root, plan, creatorDid, docId) {
|
|
|
7828
8782
|
}
|
|
7829
8783
|
|
|
7830
8784
|
// src/core/lib/flowAgent/store.ts
|
|
7831
|
-
import * as
|
|
8785
|
+
import * as Y8 from "yjs";
|
|
7832
8786
|
|
|
7833
8787
|
// src/core/lib/flowAgent/utils.ts
|
|
7834
8788
|
function stableStringify(value) {
|
|
@@ -8009,7 +8963,7 @@ function appendAgentLedgerEvent(yDoc, event) {
|
|
|
8009
8963
|
const auditMap = yDoc.getMap("auditTrail");
|
|
8010
8964
|
let arr = auditMap.get(FLOW_AGENT_AUDIT_SCOPE);
|
|
8011
8965
|
if (!arr) {
|
|
8012
|
-
arr = new
|
|
8966
|
+
arr = new Y8.Array();
|
|
8013
8967
|
auditMap.set(FLOW_AGENT_AUDIT_SCOPE, arr);
|
|
8014
8968
|
}
|
|
8015
8969
|
const fullEvent = {
|
|
@@ -8273,12 +9227,88 @@ function snapshotNode(block, runtime, now, pendingInvocationCount = 0) {
|
|
|
8273
9227
|
return snapshot;
|
|
8274
9228
|
}
|
|
8275
9229
|
|
|
9230
|
+
// src/core/lib/flowAgent/actionExecutionPolicy.ts
|
|
9231
|
+
var RUNTIME_INPUT_REQUIRED_ACTIONS = /* @__PURE__ */ new Set(["qi/form.submit", "qi/human.form.submit", "qi/human.checkbox.set", "qi/protocol.select"]);
|
|
9232
|
+
function isRecord(value) {
|
|
9233
|
+
return value != null && typeof value === "object" && !Array.isArray(value);
|
|
9234
|
+
}
|
|
9235
|
+
function parseStringList(value) {
|
|
9236
|
+
const parsed = parseJsonProp(value, []);
|
|
9237
|
+
if (!Array.isArray(parsed)) return [];
|
|
9238
|
+
return parsed.filter((item) => typeof item === "string" && item.length > 0);
|
|
9239
|
+
}
|
|
9240
|
+
function normalizeMode(value) {
|
|
9241
|
+
if (value === "saved-input" || value === "saved_input" || value === "savedInput") return "saved-input";
|
|
9242
|
+
if (value === "runtime-input-required" || value === "runtime_input_required" || value === "runtimeInputRequired") return "runtime-input-required";
|
|
9243
|
+
if (value === "human-only" || value === "human_only" || value === "humanOnly") return "human-only";
|
|
9244
|
+
return void 0;
|
|
9245
|
+
}
|
|
9246
|
+
function parseExecutionConfig(value) {
|
|
9247
|
+
if (value == null || value === "") return {};
|
|
9248
|
+
if (typeof value === "string") {
|
|
9249
|
+
const directMode = normalizeMode(value);
|
|
9250
|
+
if (directMode) return { mode: directMode };
|
|
9251
|
+
}
|
|
9252
|
+
const parsed = parseJsonProp(value, {});
|
|
9253
|
+
if (!isRecord(parsed)) return {};
|
|
9254
|
+
return {
|
|
9255
|
+
mode: normalizeMode(parsed.mode),
|
|
9256
|
+
requiredRuntimeInputs: parseStringList(parsed.requiredRuntimeInputs)
|
|
9257
|
+
};
|
|
9258
|
+
}
|
|
9259
|
+
function inferDefaultMode(actionType, requiredRuntimeInputs) {
|
|
9260
|
+
if (requiredRuntimeInputs.length > 0) return "runtime-input-required";
|
|
9261
|
+
if (actionType && RUNTIME_INPUT_REQUIRED_ACTIONS.has(actionType)) return "runtime-input-required";
|
|
9262
|
+
return "saved-input";
|
|
9263
|
+
}
|
|
9264
|
+
function getFlowAgentActionExecutionPolicy(block) {
|
|
9265
|
+
const props = getBlockProps(block);
|
|
9266
|
+
const actionType = getBlockActionType(block);
|
|
9267
|
+
const config = parseExecutionConfig(props.flowAgentExecution || props.flowAgentExecutionMode || props.agentExecutionMode);
|
|
9268
|
+
const requiredRuntimeInputs = [
|
|
9269
|
+
...config.requiredRuntimeInputs || [],
|
|
9270
|
+
...parseStringList(props.requiredRuntimeInputs || props.runtimeRequiredInputs || props.flowAgentRequiredRuntimeInputs)
|
|
9271
|
+
];
|
|
9272
|
+
return {
|
|
9273
|
+
mode: config.mode || inferDefaultMode(actionType, requiredRuntimeInputs),
|
|
9274
|
+
requiredRuntimeInputs: Array.from(new Set(requiredRuntimeInputs))
|
|
9275
|
+
};
|
|
9276
|
+
}
|
|
9277
|
+
function getCommandRuntimeInputs(payload) {
|
|
9278
|
+
return isRecord(payload.runtimeInputs) ? payload.runtimeInputs : void 0;
|
|
9279
|
+
}
|
|
9280
|
+
function validateFlowAgentExecuteActionPayload(block, payload) {
|
|
9281
|
+
const policy = getFlowAgentActionExecutionPolicy(block);
|
|
9282
|
+
if (policy.mode === "human-only") {
|
|
9283
|
+
return {
|
|
9284
|
+
valid: false,
|
|
9285
|
+
mode: policy.mode,
|
|
9286
|
+
missingRuntimeInputs: [],
|
|
9287
|
+
reason: "Action requires human execution and cannot be run by the Flow Agent"
|
|
9288
|
+
};
|
|
9289
|
+
}
|
|
9290
|
+
if (policy.mode !== "runtime-input-required") {
|
|
9291
|
+
return { valid: true, mode: policy.mode, missingRuntimeInputs: [] };
|
|
9292
|
+
}
|
|
9293
|
+
const runtimeInputs = getCommandRuntimeInputs(payload);
|
|
9294
|
+
const missingRuntimeInputs = policy.requiredRuntimeInputs.length > 0 ? policy.requiredRuntimeInputs.filter((key) => runtimeInputs?.[key] == null || runtimeInputs[key] === "") : runtimeInputs ? [] : ["runtimeInputs"];
|
|
9295
|
+
if (missingRuntimeInputs.length > 0) {
|
|
9296
|
+
return {
|
|
9297
|
+
valid: false,
|
|
9298
|
+
mode: policy.mode,
|
|
9299
|
+
missingRuntimeInputs,
|
|
9300
|
+
reason: policy.requiredRuntimeInputs.length > 0 ? `Missing required runtimeInputs: ${missingRuntimeInputs.join(", ")}` : "Action requires runtimeInputs before the Flow Agent can execute it"
|
|
9301
|
+
};
|
|
9302
|
+
}
|
|
9303
|
+
return { valid: true, mode: policy.mode, missingRuntimeInputs: [] };
|
|
9304
|
+
}
|
|
9305
|
+
|
|
8276
9306
|
// src/core/lib/flowAgent/orchestrator.ts
|
|
8277
9307
|
var BLOCKER_DIAGNOSIS_VERSION = 2;
|
|
8278
9308
|
function getBlocks(context) {
|
|
8279
9309
|
return context.blocks || context.editor?.document || [];
|
|
8280
9310
|
}
|
|
8281
|
-
function
|
|
9311
|
+
function getRuntime3(yDoc, nodeId) {
|
|
8282
9312
|
const runtime = yDoc.getMap("runtime");
|
|
8283
9313
|
const value = runtime.get(nodeId);
|
|
8284
9314
|
return value && typeof value === "object" ? value : {};
|
|
@@ -8373,6 +9403,11 @@ function queueIfAuthorized(context, options, type, nodeId, reason, payload) {
|
|
|
8373
9403
|
}
|
|
8374
9404
|
return queueAgentCommand(context.yDoc, command).created ? command : null;
|
|
8375
9405
|
}
|
|
9406
|
+
function statusForResult(result) {
|
|
9407
|
+
if (result.status) return result.status;
|
|
9408
|
+
if (!result.success) return "failed";
|
|
9409
|
+
return result.confirmed === false ? "awaiting_readback" : "confirmed";
|
|
9410
|
+
}
|
|
8376
9411
|
function planForSnapshot(context, options, block, snapshot) {
|
|
8377
9412
|
const queued = [];
|
|
8378
9413
|
const actionType = getBlockActionType(block);
|
|
@@ -8432,8 +9467,25 @@ function planForSnapshot(context, options, block, snapshot) {
|
|
|
8432
9467
|
return queued;
|
|
8433
9468
|
}
|
|
8434
9469
|
if (actionType && canQueueCommand("execute_action", snapshot.nodeId, context, options)) {
|
|
9470
|
+
const pendingInvocation = readPendingInvocations(context.yDoc, snapshot.nodeId)[0];
|
|
9471
|
+
const payload = {
|
|
9472
|
+
actionType,
|
|
9473
|
+
...pendingInvocation ? { pendingInvocationId: pendingInvocation.id } : {}
|
|
9474
|
+
};
|
|
9475
|
+
const actionValidation = validateFlowAgentExecuteActionPayload(block, payload);
|
|
9476
|
+
if (!actionValidation.valid) {
|
|
9477
|
+
const commandType = actionValidation.mode === "human-only" ? "notify_actor" : "diagnose_blocker";
|
|
9478
|
+
const command2 = queueIfAuthorized(context, options, commandType, snapshot.nodeId, actionValidation.reason || "Action node cannot be executed by Flow Agent yet", {
|
|
9479
|
+
cause: actionValidation.mode === "runtime-input-required" ? "missing_input" : "unknown",
|
|
9480
|
+
requiredActionType: actionType,
|
|
9481
|
+
requiredRuntimeInputs: actionValidation.missingRuntimeInputs,
|
|
9482
|
+
severity: actionValidation.mode === "human-only" ? "attention" : void 0
|
|
9483
|
+
});
|
|
9484
|
+
if (command2) queued.push(command2);
|
|
9485
|
+
return queued;
|
|
9486
|
+
}
|
|
8435
9487
|
const command = queueIfAuthorized(context, options, "execute_action", snapshot.nodeId, "Action node is pending and executable", {
|
|
8436
|
-
|
|
9488
|
+
...payload
|
|
8437
9489
|
});
|
|
8438
9490
|
if (command) queued.push(command);
|
|
8439
9491
|
return queued;
|
|
@@ -8455,7 +9507,7 @@ function planRalphLoopCommands(context, options = {}) {
|
|
|
8455
9507
|
const nodeId = getBlockId(block);
|
|
8456
9508
|
if (!nodeId) continue;
|
|
8457
9509
|
const pendingInvocationCount = readPendingInvocations(context.yDoc, nodeId).length;
|
|
8458
|
-
const snapshot = snapshotNode(block,
|
|
9510
|
+
const snapshot = snapshotNode(block, getRuntime3(context.yDoc, nodeId), now, pendingInvocationCount);
|
|
8459
9511
|
snapshots.push(snapshot);
|
|
8460
9512
|
queuedCommands.push(...planForSnapshot(context, options, block, snapshot));
|
|
8461
9513
|
}
|
|
@@ -8538,7 +9590,7 @@ async function executeQueuedAgentCommands(context, options = {}) {
|
|
|
8538
9590
|
continue;
|
|
8539
9591
|
}
|
|
8540
9592
|
updateAgentCommand(context.yDoc, command.id, {
|
|
8541
|
-
status: result
|
|
9593
|
+
status: statusForResult(result),
|
|
8542
9594
|
error: result.error,
|
|
8543
9595
|
updatedAt: context.now?.() || Date.now()
|
|
8544
9596
|
});
|
|
@@ -8587,7 +9639,7 @@ function safeAppendAgentLedgerEvent2(yDoc, event) {
|
|
|
8587
9639
|
throw error;
|
|
8588
9640
|
}
|
|
8589
9641
|
}
|
|
8590
|
-
function
|
|
9642
|
+
function createYDocRuntimeManager2(yDoc) {
|
|
8591
9643
|
const runtime = yDoc.getMap("runtime");
|
|
8592
9644
|
return {
|
|
8593
9645
|
get: (nodeId) => {
|
|
@@ -8618,19 +9670,16 @@ function clearRuntimeBlocker(yDoc, nodeId, updates) {
|
|
|
8618
9670
|
});
|
|
8619
9671
|
}
|
|
8620
9672
|
function findContextBlock(context, nodeId) {
|
|
8621
|
-
const block = (context.blocks || []).find((entry) => getBlockId(entry) === nodeId);
|
|
9673
|
+
const block = (context.blocks || context.editor?.document || []).find((entry) => getBlockId(entry) === nodeId);
|
|
8622
9674
|
return block && typeof block === "object" ? block : null;
|
|
8623
9675
|
}
|
|
8624
|
-
function parseInputs2(value) {
|
|
8625
|
-
return parseJsonProp(value, {});
|
|
8626
|
-
}
|
|
8627
9676
|
function getXmlAttribute(element, key) {
|
|
8628
9677
|
return element.getAttribute(key);
|
|
8629
9678
|
}
|
|
8630
9679
|
function setXmlAttribute(element, key, value) {
|
|
8631
9680
|
element.setAttribute(key, value);
|
|
8632
9681
|
}
|
|
8633
|
-
function
|
|
9682
|
+
function isRecord2(value) {
|
|
8634
9683
|
return value != null && typeof value === "object" && !Array.isArray(value);
|
|
8635
9684
|
}
|
|
8636
9685
|
function isYXmlContainerLike(value) {
|
|
@@ -8643,13 +9692,13 @@ function getElementBlockId(element) {
|
|
|
8643
9692
|
const directId = getXmlAttribute(element, "id");
|
|
8644
9693
|
if (typeof directId === "string" && directId.length > 0) return directId;
|
|
8645
9694
|
const attrs = getXmlAttribute(element, "attrs");
|
|
8646
|
-
const attrsId =
|
|
9695
|
+
const attrsId = isRecord2(attrs) ? attrs.id : void 0;
|
|
8647
9696
|
return typeof attrsId === "string" && attrsId.length > 0 ? attrsId : void 0;
|
|
8648
9697
|
}
|
|
8649
9698
|
function updateXmlElementProps(element, blockId, propsPatch) {
|
|
8650
9699
|
const attrs = getXmlAttribute(element, "attrs");
|
|
8651
|
-
if (
|
|
8652
|
-
const existingProps =
|
|
9700
|
+
if (isRecord2(attrs)) {
|
|
9701
|
+
const existingProps = isRecord2(attrs.props) ? attrs.props : {};
|
|
8653
9702
|
setXmlAttribute(element, "attrs", {
|
|
8654
9703
|
...attrs,
|
|
8655
9704
|
id: typeof attrs.id === "string" ? attrs.id : blockId,
|
|
@@ -8706,7 +9755,7 @@ function assignActorInYDoc(yDoc, command, context) {
|
|
|
8706
9755
|
if (!updatedDocument) {
|
|
8707
9756
|
throw new Error(`Block ${command.nodeId} was not found for assignment`);
|
|
8708
9757
|
}
|
|
8709
|
-
const runtime =
|
|
9758
|
+
const runtime = createYDocRuntimeManager2(yDoc);
|
|
8710
9759
|
runtime.update(command.nodeId, {
|
|
8711
9760
|
assignedActorDid: targetActorDid,
|
|
8712
9761
|
assignedByDid: context.actor.did,
|
|
@@ -8751,76 +9800,69 @@ async function executeActionCommand(command, context, options) {
|
|
|
8751
9800
|
if (!actionType) {
|
|
8752
9801
|
return { commandId: command.id, success: false, error: "execute_action command is missing payload.actionType" };
|
|
8753
9802
|
}
|
|
8754
|
-
const action = getAction(actionType);
|
|
8755
|
-
if (!action) {
|
|
8756
|
-
return { commandId: command.id, success: false, error: `No registered action found for ${actionType}` };
|
|
8757
|
-
}
|
|
8758
9803
|
const block = findContextBlock(context, command.nodeId);
|
|
8759
9804
|
if (!block) {
|
|
8760
9805
|
return { commandId: command.id, success: false, error: `Block ${command.nodeId} was not found in runtime context` };
|
|
8761
9806
|
}
|
|
8762
9807
|
const props = getBlockProps(block);
|
|
8763
|
-
|
|
8764
|
-
|
|
8765
|
-
|
|
8766
|
-
|
|
8767
|
-
|
|
9808
|
+
if (typeof props.actionType === "string" && props.actionType !== actionType) {
|
|
9809
|
+
return {
|
|
9810
|
+
commandId: command.id,
|
|
9811
|
+
success: false,
|
|
9812
|
+
error: `execute_action payload.actionType ${actionType} does not match block actionType ${props.actionType}`
|
|
9813
|
+
};
|
|
9814
|
+
}
|
|
9815
|
+
const runtimeInputs = command.payload.runtimeInputs;
|
|
9816
|
+
if (runtimeInputs != null && !isRecord2(runtimeInputs)) {
|
|
9817
|
+
return { commandId: command.id, success: false, error: "execute_action payload.runtimeInputs must be an object when provided" };
|
|
9818
|
+
}
|
|
9819
|
+
const inputValidation = validateFlowAgentExecuteActionPayload(block, command.payload);
|
|
9820
|
+
if (!inputValidation.valid) {
|
|
9821
|
+
return {
|
|
9822
|
+
commandId: command.id,
|
|
9823
|
+
success: false,
|
|
9824
|
+
confirmed: false,
|
|
9825
|
+
status: inputValidation.mode === "human-only" ? "skipped" : "failed",
|
|
9826
|
+
error: inputValidation.reason
|
|
9827
|
+
};
|
|
9828
|
+
}
|
|
9829
|
+
const pendingInvocationId = typeof command.payload.pendingInvocationId === "string" ? command.payload.pendingInvocationId : void 0;
|
|
9830
|
+
const outcome = await executeActionBlock({
|
|
9831
|
+
editorOrYDoc: context.editor || context.yDoc,
|
|
9832
|
+
block,
|
|
9833
|
+
blockId: command.nodeId,
|
|
9834
|
+
document: context.blocks || context.editor?.document || [],
|
|
8768
9835
|
actorDid: context.actor.did,
|
|
8769
9836
|
actorType: options.actorType,
|
|
8770
9837
|
entityRoomId: options.entityRoomId,
|
|
8771
|
-
|
|
8772
|
-
|
|
8773
|
-
|
|
8774
|
-
|
|
8775
|
-
|
|
8776
|
-
|
|
8777
|
-
|
|
8778
|
-
|
|
8779
|
-
|
|
8780
|
-
|
|
8781
|
-
|
|
8782
|
-
|
|
8783
|
-
actorDid: context.actor.did,
|
|
8784
|
-
flowId: context.flowId,
|
|
8785
|
-
flowUri: context.flowUri,
|
|
8786
|
-
nodeId: command.nodeId,
|
|
8787
|
-
flowNode,
|
|
8788
|
-
runtime,
|
|
8789
|
-
services: options.actionServices || {}
|
|
8790
|
-
});
|
|
8791
|
-
return { payload: result.output };
|
|
8792
|
-
},
|
|
8793
|
-
pin: options.pin
|
|
9838
|
+
ucanService: options.ucanService,
|
|
9839
|
+
invocationStore: options.invocationStore,
|
|
9840
|
+
services: options.actionServices || {},
|
|
9841
|
+
handlers: options.actionHandlers,
|
|
9842
|
+
runtimeInputs: getCommandRuntimeInputs(command.payload),
|
|
9843
|
+
pendingInvocationId,
|
|
9844
|
+
pin: options.pin,
|
|
9845
|
+
flowUri: context.flowUri,
|
|
9846
|
+
flowId: context.flowId,
|
|
9847
|
+
flowOwnerDid: options.flowOwnerDid || "",
|
|
9848
|
+
schemaVersion: options.schemaVersion || DEFAULT_SCHEMA_VERSION,
|
|
9849
|
+
now: options.now || context.now
|
|
8794
9850
|
});
|
|
8795
|
-
if (outcome.success && outcome.result) {
|
|
8796
|
-
runtime.update(command.nodeId, {
|
|
8797
|
-
state: "completed",
|
|
8798
|
-
output: outcome.result.payload || {},
|
|
8799
|
-
executedByDid: context.actor.did,
|
|
8800
|
-
executedAt: options.now?.() || context.now?.() || Date.now(),
|
|
8801
|
-
lastInvocationCid: outcome.invocationCid || outcome.capabilityId,
|
|
8802
|
-
lastCommandId: command.id
|
|
8803
|
-
});
|
|
8804
|
-
} else if (!outcome.success) {
|
|
8805
|
-
runtime.update(command.nodeId, {
|
|
8806
|
-
state: "failed",
|
|
8807
|
-
error: {
|
|
8808
|
-
message: outcome.error || "Unknown execution error",
|
|
8809
|
-
at: options.now?.() || context.now?.() || Date.now(),
|
|
8810
|
-
commandId: command.id
|
|
8811
|
-
},
|
|
8812
|
-
lastCommandId: command.id
|
|
8813
|
-
});
|
|
8814
|
-
}
|
|
8815
9851
|
return {
|
|
8816
9852
|
commandId: command.id,
|
|
8817
9853
|
success: outcome.success,
|
|
8818
|
-
confirmed: outcome.success,
|
|
9854
|
+
confirmed: outcome.success && outcome.completionState === "completed",
|
|
8819
9855
|
output: {
|
|
8820
|
-
...outcome.
|
|
8821
|
-
...outcome.invocationCid ? { invocationCid: outcome.invocationCid } : {}
|
|
9856
|
+
...outcome.output && typeof outcome.output === "object" ? outcome.output : {},
|
|
9857
|
+
...outcome.invocationCid ? { invocationCid: outcome.invocationCid } : {},
|
|
9858
|
+
...outcome.capabilityId ? { capabilityId: outcome.capabilityId } : {},
|
|
9859
|
+
...outcome.runId ? { runId: outcome.runId } : {},
|
|
9860
|
+
...outcome.events.length > 0 ? { events: outcome.events } : {},
|
|
9861
|
+
...pendingInvocationId ? { pendingInvocationId, pendingInvocationRemoved: outcome.pendingInvocationRemoved } : {},
|
|
9862
|
+
completionState: outcome.completionState
|
|
8822
9863
|
},
|
|
8823
|
-
error: outcome.error
|
|
9864
|
+
error: outcome.error,
|
|
9865
|
+
completionState: outcome.completionState
|
|
8824
9866
|
};
|
|
8825
9867
|
}
|
|
8826
9868
|
function getRecoverableBlockerReason(runtime) {
|
|
@@ -8915,6 +9957,11 @@ async function callConfiguredExecutor(command, context, options) {
|
|
|
8915
9957
|
return void 0;
|
|
8916
9958
|
}
|
|
8917
9959
|
}
|
|
9960
|
+
function statusForResult2(result) {
|
|
9961
|
+
if (result.status) return result.status;
|
|
9962
|
+
if (!result.success) return "failed";
|
|
9963
|
+
return result.confirmed === false ? "awaiting_readback" : "confirmed";
|
|
9964
|
+
}
|
|
8918
9965
|
async function executeQueuedFlowAgentCoreCommands(context, options) {
|
|
8919
9966
|
const now = options.now?.() || context.now?.() || Date.now();
|
|
8920
9967
|
const { leases } = getFlowAgentMaps(context.yDoc);
|
|
@@ -8968,7 +10015,7 @@ async function executeQueuedFlowAgentCoreCommands(context, options) {
|
|
|
8968
10015
|
continue;
|
|
8969
10016
|
}
|
|
8970
10017
|
updateAgentCommand(context.yDoc, command.id, {
|
|
8971
|
-
status: normalized
|
|
10018
|
+
status: statusForResult2(normalized),
|
|
8972
10019
|
error: normalized.error,
|
|
8973
10020
|
updatedAt: options.now?.() || context.now?.() || Date.now()
|
|
8974
10021
|
});
|
|
@@ -9085,9 +10132,10 @@ export {
|
|
|
9085
10132
|
buildFlowNodeFromBlock,
|
|
9086
10133
|
createRuntimeStateManager,
|
|
9087
10134
|
clearRuntimeForTemplateClone,
|
|
10135
|
+
isRuntimeRef,
|
|
10136
|
+
resolveRuntimeRefs,
|
|
9088
10137
|
isAuthorized,
|
|
9089
10138
|
executeNode,
|
|
9090
|
-
isRuntimeRef,
|
|
9091
10139
|
RUN_RECORD_AUDIT_TYPE,
|
|
9092
10140
|
computePendingInvocationId,
|
|
9093
10141
|
snapshotInputRefs,
|
|
@@ -9102,6 +10150,9 @@ export {
|
|
|
9102
10150
|
replayFailedListenerRun,
|
|
9103
10151
|
reconcilePendingInvocations,
|
|
9104
10152
|
getActionForBlock,
|
|
10153
|
+
reconcileActionReadBack,
|
|
10154
|
+
buildActionRunInputs,
|
|
10155
|
+
executeActionBlock,
|
|
9105
10156
|
writeRunRecordAndReconcile,
|
|
9106
10157
|
compileBaseUcanFlow,
|
|
9107
10158
|
readCompiledFlowFromYDoc,
|
|
@@ -9143,4 +10194,4 @@ export {
|
|
|
9143
10194
|
executeQueuedFlowAgentCoreCommands,
|
|
9144
10195
|
FlowAgentService
|
|
9145
10196
|
};
|
|
9146
|
-
//# sourceMappingURL=chunk-
|
|
10197
|
+
//# sourceMappingURL=chunk-OK3ILV2C.mjs.map
|