@arke-institute/klados-testing 0.1.2 → 0.3.0

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.
@@ -24,6 +24,8 @@ export declare function getEntity(id: string): Promise<Entity>;
24
24
  /**
25
25
  * Delete an entity
26
26
  *
27
+ * Fetches the entity tip first for CAS protection, then deletes.
28
+ *
27
29
  * @param id - Entity ID to delete
28
30
  */
29
31
  export declare function deleteEntity(id: string): Promise<void>;
@@ -1 +1 @@
1
- {"version":3,"file":"entities.d.ts","sourceRoot":"","sources":["../src/entities.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,KAAK,EACV,MAAM,EACN,UAAU,EACV,kBAAkB,EAClB,mBAAmB,EACnB,uBAAuB,EACxB,MAAM,YAAY,CAAC;AAEpB;;;;;;;;;;;GAWG;AACH,wBAAsB,YAAY,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,MAAM,CAAC,CAWhF;AAED;;;;GAIG;AACH,wBAAsB,SAAS,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAE3D;AAED;;;;GAIG;AACH,wBAAsB,YAAY,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAE5D;AAED;;;;;;;;;;;;GAYG;AACH,wBAAsB,gBAAgB,CACpC,OAAO,EAAE,uBAAuB,GAC/B,OAAO,CAAC,UAAU,CAAC,CAMrB;AAED;;;;;;;GAOG;AACH,wBAAsB,qBAAqB,CACzC,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,kBAAkB,CAAC,CAK7B"}
1
+ {"version":3,"file":"entities.d.ts","sourceRoot":"","sources":["../src/entities.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,KAAK,EACV,MAAM,EACN,UAAU,EACV,kBAAkB,EAClB,mBAAmB,EACnB,uBAAuB,EACxB,MAAM,YAAY,CAAC;AAEpB;;;;;;;;;;;GAWG;AACH,wBAAsB,YAAY,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,MAAM,CAAC,CAWhF;AAED;;;;GAIG;AACH,wBAAsB,SAAS,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAE3D;AAED;;;;;;GAMG;AACH,wBAAsB,YAAY,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAQ5D;AAED;;;;;;;;;;;;GAYG;AACH,wBAAsB,gBAAgB,CACpC,OAAO,EAAE,uBAAuB,GAC/B,OAAO,CAAC,UAAU,CAAC,CAMrB;AAED;;;;;;;GAOG;AACH,wBAAsB,qBAAqB,CACzC,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,kBAAkB,CAAC,CAK7B"}
package/dist/entities.js CHANGED
@@ -35,10 +35,17 @@ export async function getEntity(id) {
35
35
  /**
36
36
  * Delete an entity
37
37
  *
38
+ * Fetches the entity tip first for CAS protection, then deletes.
39
+ *
38
40
  * @param id - Entity ID to delete
39
41
  */
40
42
  export async function deleteEntity(id) {
41
- await apiRequest('DELETE', `/entities/${id}`);
43
+ // Get current tip for CAS
44
+ const tip = await apiRequest('GET', `/entities/${id}/tip`);
45
+ // Delete with expect_tip
46
+ await apiRequest('DELETE', `/entities/${id}`, {
47
+ expect_tip: tip.cid,
48
+ });
42
49
  }
43
50
  /**
44
51
  * Create a new collection
@@ -1 +1 @@
1
- {"version":3,"file":"entities.js","sourceRoot":"","sources":["../src/entities.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AASzC;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,OAA4B;IAC7D,MAAM,IAAI,GAA4B;QACpC,IAAI,EAAE,OAAO,CAAC,IAAI;QAClB,UAAU,EAAE,OAAO,CAAC,UAAU;KAC/B,CAAC;IAEF,IAAI,OAAO,CAAC,YAAY,EAAE,CAAC;QACzB,IAAI,CAAC,UAAU,GAAG,OAAO,CAAC,YAAY,CAAC;IACzC,CAAC;IAED,OAAO,UAAU,CAAS,MAAM,EAAE,WAAW,EAAE,IAAI,CAAC,CAAC;AACvD,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,EAAU;IACxC,OAAO,UAAU,CAAS,KAAK,EAAE,aAAa,EAAE,EAAE,CAAC,CAAC;AACtD,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,EAAU;IAC3C,MAAM,UAAU,CAAC,QAAQ,EAAE,aAAa,EAAE,EAAE,CAAC,CAAC;AAChD,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,OAAgC;IAEhC,OAAO,UAAU,CAAa,MAAM,EAAE,cAAc,EAAE;QACpD,KAAK,EAAE,OAAO,CAAC,KAAK;QACpB,WAAW,EAAE,OAAO,CAAC,WAAW;QAChC,aAAa,EAAE,OAAO,CAAC,YAAY;KACpC,CAAC,CAAC;AACL,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,qBAAqB,CACzC,YAAoB;IAEpB,OAAO,UAAU,CACf,KAAK,EACL,gBAAgB,YAAY,WAAW,CACxC,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"entities.js","sourceRoot":"","sources":["../src/entities.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AASzC;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,OAA4B;IAC7D,MAAM,IAAI,GAA4B;QACpC,IAAI,EAAE,OAAO,CAAC,IAAI;QAClB,UAAU,EAAE,OAAO,CAAC,UAAU;KAC/B,CAAC;IAEF,IAAI,OAAO,CAAC,YAAY,EAAE,CAAC;QACzB,IAAI,CAAC,UAAU,GAAG,OAAO,CAAC,YAAY,CAAC;IACzC,CAAC;IAED,OAAO,UAAU,CAAS,MAAM,EAAE,WAAW,EAAE,IAAI,CAAC,CAAC;AACvD,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,EAAU;IACxC,OAAO,UAAU,CAAS,KAAK,EAAE,aAAa,EAAE,EAAE,CAAC,CAAC;AACtD,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,EAAU;IAC3C,0BAA0B;IAC1B,MAAM,GAAG,GAAG,MAAM,UAAU,CAAkB,KAAK,EAAE,aAAa,EAAE,MAAM,CAAC,CAAC;IAE5E,yBAAyB;IACzB,MAAM,UAAU,CAAC,QAAQ,EAAE,aAAa,EAAE,EAAE,EAAE;QAC5C,UAAU,EAAE,GAAG,CAAC,GAAG;KACpB,CAAC,CAAC;AACL,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,OAAgC;IAEhC,OAAO,UAAU,CAAa,MAAM,EAAE,cAAc,EAAE;QACpD,KAAK,EAAE,OAAO,CAAC,KAAK;QACpB,WAAW,EAAE,OAAO,CAAC,WAAW;QAChC,aAAa,EAAE,OAAO,CAAC,YAAY;KACpC,CAAC,CAAC;AACL,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,qBAAqB,CACzC,YAAoB;IAEpB,OAAO,UAAU,CACf,KAAK,EACL,gBAAgB,YAAY,WAAW,CACxC,CAAC;AACJ,CAAC"}
package/dist/index.d.ts CHANGED
@@ -53,8 +53,10 @@
53
53
  */
54
54
  export { configureTestClient, getConfig, resetTestClient, apiRequest, sleep, log } from './client.js';
55
55
  export { createEntity, getEntity, deleteEntity, createCollection, getCollectionEntities } from './entities.js';
56
- export { getKladosLog, getFirstLogFromCollection, waitForKladosLog, getLogMessages, getLogEntry } from './logs.js';
56
+ export { getKladosLog, getFirstLogFromCollection, waitForKladosLog, getLogMessages, getLogEntry, getLogChildren, buildWorkflowTree, waitForWorkflowTree, } from './logs.js';
57
57
  export { invokeKlados } from './invoke.js';
58
+ export { invokeRhiza, createRhiza, getWorkflowLogs, waitForWorkflowCompletion, assertWorkflowCompleted, assertWorkflowPath, } from './workflows.js';
58
59
  export { assertLogCompleted, assertLogFailed, assertLogHasMessages, assertLogMessageCount, assertLogHasHandoff, } from './assertions.js';
59
- export type { TestConfig, Entity, Collection, CollectionEntities, InvokeResult, LogMessage, KladosLogEntry, CreateEntityOptions, CreateCollectionOptions, InvokeKladosOptions, WaitForLogOptions, LogMessageCriteria, } from './types.js';
60
+ export type { TestConfig, Entity, Collection, CollectionEntities, InvokeResult, LogMessage, KladosLogEntry, CreateEntityOptions, CreateCollectionOptions, InvokeKladosOptions, WaitForLogOptions, LogMessageCriteria, LogTreeNode, WorkflowLogTree, WaitForWorkflowTreeOptions, } from './types.js';
61
+ export type { InvokeRhizaOptions, InvokeRhizaResult, WorkflowCompletionResult, CreateRhizaOptions, FlowStep, ThenSpec, } from './workflows.js';
60
62
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoDG;AAGH,OAAO,EAAE,mBAAmB,EAAE,SAAS,EAAE,eAAe,EAAE,UAAU,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,aAAa,CAAC;AAGtG,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,YAAY,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AAG/G,OAAO,EAAE,YAAY,EAAE,yBAAyB,EAAE,gBAAgB,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAGnH,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAG3C,OAAO,EACL,kBAAkB,EAClB,eAAe,EACf,oBAAoB,EACpB,qBAAqB,EACrB,mBAAmB,GACpB,MAAM,iBAAiB,CAAC;AAGzB,YAAY,EACV,UAAU,EACV,MAAM,EACN,UAAU,EACV,kBAAkB,EAClB,YAAY,EACZ,UAAU,EACV,cAAc,EACd,mBAAmB,EACnB,uBAAuB,EACvB,mBAAmB,EACnB,iBAAiB,EACjB,kBAAkB,GACnB,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoDG;AAGH,OAAO,EAAE,mBAAmB,EAAE,SAAS,EAAE,eAAe,EAAE,UAAU,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,aAAa,CAAC;AAGtG,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,YAAY,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AAG/G,OAAO,EACL,YAAY,EACZ,yBAAyB,EACzB,gBAAgB,EAChB,cAAc,EACd,WAAW,EAEX,cAAc,EACd,iBAAiB,EACjB,mBAAmB,GACpB,MAAM,WAAW,CAAC;AAGnB,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAG3C,OAAO,EACL,WAAW,EACX,WAAW,EACX,eAAe,EACf,yBAAyB,EACzB,uBAAuB,EACvB,kBAAkB,GACnB,MAAM,gBAAgB,CAAC;AAGxB,OAAO,EACL,kBAAkB,EAClB,eAAe,EACf,oBAAoB,EACpB,qBAAqB,EACrB,mBAAmB,GACpB,MAAM,iBAAiB,CAAC;AAGzB,YAAY,EACV,UAAU,EACV,MAAM,EACN,UAAU,EACV,kBAAkB,EAClB,YAAY,EACZ,UAAU,EACV,cAAc,EACd,mBAAmB,EACnB,uBAAuB,EACvB,mBAAmB,EACnB,iBAAiB,EACjB,kBAAkB,EAElB,WAAW,EACX,eAAe,EACf,0BAA0B,GAC3B,MAAM,YAAY,CAAC;AAGpB,YAAY,EACV,kBAAkB,EAClB,iBAAiB,EACjB,wBAAwB,EACxB,kBAAkB,EAClB,QAAQ,EACR,QAAQ,GACT,MAAM,gBAAgB,CAAC"}
package/dist/index.js CHANGED
@@ -56,9 +56,13 @@ export { configureTestClient, getConfig, resetTestClient, apiRequest, sleep, log
56
56
  // Entity operations
57
57
  export { createEntity, getEntity, deleteEntity, createCollection, getCollectionEntities } from './entities.js';
58
58
  // Log utilities
59
- export { getKladosLog, getFirstLogFromCollection, waitForKladosLog, getLogMessages, getLogEntry } from './logs.js';
59
+ export { getKladosLog, getFirstLogFromCollection, waitForKladosLog, getLogMessages, getLogEntry,
60
+ // Tree-based traversal
61
+ getLogChildren, buildWorkflowTree, waitForWorkflowTree, } from './logs.js';
60
62
  // Klados invocation
61
63
  export { invokeKlados } from './invoke.js';
64
+ // Workflow utilities
65
+ export { invokeRhiza, createRhiza, getWorkflowLogs, waitForWorkflowCompletion, assertWorkflowCompleted, assertWorkflowPath, } from './workflows.js';
62
66
  // Assertions
63
67
  export { assertLogCompleted, assertLogFailed, assertLogHasMessages, assertLogMessageCount, assertLogHasHandoff, } from './assertions.js';
64
68
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoDG;AAEH,gBAAgB;AAChB,OAAO,EAAE,mBAAmB,EAAE,SAAS,EAAE,eAAe,EAAE,UAAU,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,aAAa,CAAC;AAEtG,oBAAoB;AACpB,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,YAAY,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AAE/G,gBAAgB;AAChB,OAAO,EAAE,YAAY,EAAE,yBAAyB,EAAE,gBAAgB,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAEnH,oBAAoB;AACpB,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,aAAa;AACb,OAAO,EACL,kBAAkB,EAClB,eAAe,EACf,oBAAoB,EACpB,qBAAqB,EACrB,mBAAmB,GACpB,MAAM,iBAAiB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoDG;AAEH,gBAAgB;AAChB,OAAO,EAAE,mBAAmB,EAAE,SAAS,EAAE,eAAe,EAAE,UAAU,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,aAAa,CAAC;AAEtG,oBAAoB;AACpB,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,YAAY,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AAE/G,gBAAgB;AAChB,OAAO,EACL,YAAY,EACZ,yBAAyB,EACzB,gBAAgB,EAChB,cAAc,EACd,WAAW;AACX,uBAAuB;AACvB,cAAc,EACd,iBAAiB,EACjB,mBAAmB,GACpB,MAAM,WAAW,CAAC;AAEnB,oBAAoB;AACpB,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,qBAAqB;AACrB,OAAO,EACL,WAAW,EACX,WAAW,EACX,eAAe,EACf,yBAAyB,EACzB,uBAAuB,EACvB,kBAAkB,GACnB,MAAM,gBAAgB,CAAC;AAExB,aAAa;AACb,OAAO,EACL,kBAAkB,EAClB,eAAe,EACf,oBAAoB,EACpB,qBAAqB,EACrB,mBAAmB,GACpB,MAAM,iBAAiB,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"invoke.d.ts","sourceRoot":"","sources":["../src/invoke.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAEpE;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAsB,YAAY,CAChC,OAAO,EAAE,mBAAmB,GAC3B,OAAO,CAAC,YAAY,CAAC,CAwBvB"}
1
+ {"version":3,"file":"invoke.d.ts","sourceRoot":"","sources":["../src/invoke.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAEpE;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAsB,YAAY,CAChC,OAAO,EAAE,mBAAmB,GAC3B,OAAO,CAAC,YAAY,CAAC,CA2BvB"}
package/dist/invoke.js CHANGED
@@ -26,9 +26,11 @@ import { apiRequest } from './client.js';
26
26
  export async function invokeKlados(options) {
27
27
  const body = {
28
28
  target_collection: options.targetCollection,
29
- job_collection: options.jobCollection,
30
29
  confirm: options.confirm ?? true,
31
30
  };
31
+ if (options.jobCollection) {
32
+ body.job_collection = options.jobCollection;
33
+ }
32
34
  if (options.targetEntity) {
33
35
  body.target_entity = options.targetEntity;
34
36
  }
@@ -1 +1 @@
1
- {"version":3,"file":"invoke.js","sourceRoot":"","sources":["../src/invoke.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAGzC;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,OAA4B;IAE5B,MAAM,IAAI,GAA4B;QACpC,iBAAiB,EAAE,OAAO,CAAC,gBAAgB;QAC3C,cAAc,EAAE,OAAO,CAAC,aAAa;QACrC,OAAO,EAAE,OAAO,CAAC,OAAO,IAAI,IAAI;KACjC,CAAC;IAEF,IAAI,OAAO,CAAC,YAAY,EAAE,CAAC;QACzB,IAAI,CAAC,aAAa,GAAG,OAAO,CAAC,YAAY,CAAC;IAC5C,CAAC;IAED,IAAI,OAAO,CAAC,cAAc,EAAE,CAAC;QAC3B,IAAI,CAAC,eAAe,GAAG,OAAO,CAAC,cAAc,CAAC;IAChD,CAAC;IAED,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;QAClB,IAAI,CAAC,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC;IAC7B,CAAC;IAED,OAAO,UAAU,CACf,MAAM,EACN,WAAW,OAAO,CAAC,QAAQ,SAAS,EACpC,IAAI,CACL,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"invoke.js","sourceRoot":"","sources":["../src/invoke.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAGzC;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,OAA4B;IAE5B,MAAM,IAAI,GAA4B;QACpC,iBAAiB,EAAE,OAAO,CAAC,gBAAgB;QAC3C,OAAO,EAAE,OAAO,CAAC,OAAO,IAAI,IAAI;KACjC,CAAC;IAEF,IAAI,OAAO,CAAC,aAAa,EAAE,CAAC;QAC1B,IAAI,CAAC,cAAc,GAAG,OAAO,CAAC,aAAa,CAAC;IAC9C,CAAC;IAED,IAAI,OAAO,CAAC,YAAY,EAAE,CAAC;QACzB,IAAI,CAAC,aAAa,GAAG,OAAO,CAAC,YAAY,CAAC;IAC5C,CAAC;IAED,IAAI,OAAO,CAAC,cAAc,EAAE,CAAC;QAC3B,IAAI,CAAC,eAAe,GAAG,OAAO,CAAC,cAAc,CAAC;IAChD,CAAC;IAED,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;QAClB,IAAI,CAAC,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC;IAC7B,CAAC;IAED,OAAO,UAAU,CACf,MAAM,EACN,WAAW,OAAO,CAAC,QAAQ,SAAS,EACpC,IAAI,CACL,CAAC;AACJ,CAAC"}
package/dist/logs.d.ts CHANGED
@@ -1,7 +1,9 @@
1
1
  /**
2
2
  * Klados log utilities for testing
3
+ *
4
+ * Includes tree-based traversal for multi-step workflows and scatter/gather operations.
3
5
  */
4
- import type { KladosLogEntry, WaitForLogOptions } from './types.js';
6
+ import type { KladosLogEntry, WaitForLogOptions, WorkflowLogTree, WaitForWorkflowTreeOptions } from './types.js';
5
7
  /**
6
8
  * Get a klados log entry by ID
7
9
  *
@@ -85,4 +87,77 @@ export declare function getLogEntry(log: KladosLogEntry): {
85
87
  retryable: boolean;
86
88
  };
87
89
  };
90
+ /**
91
+ * Get children of a log by querying for outgoing sent_to relationships
92
+ *
93
+ * In the Rhiza log tree:
94
+ * - Parents have `sent_to` outgoing relationships pointing to children
95
+ * - Children have `received_from` outgoing relationships pointing to parents
96
+ * - We use `sent_to` for traversal since it's an outgoing relationship (no indexing lag)
97
+ *
98
+ * @param logEntityId - Log entity ID to find children of
99
+ * @returns Array of child log entity IDs
100
+ */
101
+ export declare function getLogChildren(logEntityId: string): Promise<string[]>;
102
+ /**
103
+ * Build a snapshot of the workflow log tree
104
+ *
105
+ * This traverses the log tree starting from the first_log relationship
106
+ * on the job collection, following incoming received_from relationships
107
+ * to discover all logs in the workflow.
108
+ *
109
+ * @example
110
+ * ```typescript
111
+ * const tree = await buildWorkflowTree(jobCollectionId);
112
+ *
113
+ * if (tree.isComplete) {
114
+ * console.log('Workflow finished with', tree.logs.size, 'logs');
115
+ * if (tree.hasErrors) {
116
+ * console.log('Errors:', tree.errors);
117
+ * }
118
+ * }
119
+ * ```
120
+ *
121
+ * @param jobCollectionId - Job collection ID
122
+ * @returns Current state of the workflow log tree
123
+ */
124
+ export declare function buildWorkflowTree(jobCollectionId: string): Promise<WorkflowLogTree>;
125
+ /**
126
+ * Wait for a workflow to complete by polling the log tree
127
+ *
128
+ * This function properly handles:
129
+ * - Multi-step workflows (A → B → C)
130
+ * - Scatter operations (A → [B1, B2, B3])
131
+ * - Nested scatters
132
+ * - Gather operations
133
+ * - Mixed success/error branches
134
+ *
135
+ * Unlike `waitForKladosLog` which only checks the first log, this function
136
+ * traverses the entire log tree and waits for ALL branches to complete.
137
+ *
138
+ * @example
139
+ * ```typescript
140
+ * // Wait for a scatter workflow to complete
141
+ * const tree = await waitForWorkflowTree(jobCollectionId, {
142
+ * timeout: 60000,
143
+ * pollInterval: 2000,
144
+ * });
145
+ *
146
+ * if (tree.isComplete) {
147
+ * console.log('All', tree.logs.size, 'logs completed');
148
+ * if (tree.hasErrors) {
149
+ * console.log('Some branches failed:', tree.errors);
150
+ * } else {
151
+ * console.log('Workflow succeeded!');
152
+ * }
153
+ * } else {
154
+ * console.log('Workflow timed out');
155
+ * }
156
+ * ```
157
+ *
158
+ * @param jobCollectionId - Job collection ID
159
+ * @param options - Wait options
160
+ * @returns Final state of the workflow log tree
161
+ */
162
+ export declare function waitForWorkflowTree(jobCollectionId: string, options?: WaitForWorkflowTreeOptions): Promise<WorkflowLogTree>;
88
163
  //# sourceMappingURL=logs.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"logs.d.ts","sourceRoot":"","sources":["../src/logs.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,KAAK,EAAU,cAAc,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAE5E;;;;GAIG;AACH,wBAAsB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC,CAEzE;AAED;;;;;;;;GAQG;AACH,wBAAsB,yBAAyB,CAC7C,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CASxB;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAsB,gBAAgB,CACpC,eAAe,EAAE,MAAM,EACvB,OAAO,CAAC,EAAE,iBAAiB,GAC1B,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,CA0BhC;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,cAAc,qCAEjD;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,cAAc;;;;;;;;qBAvB1B,CAAC;uBAGlB,CAAH;;iBAOU,CAAC;aAA2B,CAAC;;;;;;;;;;cAaD,CAAC;aAC1B,CAAC;;;;;;;EACd"}
1
+ {"version":3,"file":"logs.d.ts","sourceRoot":"","sources":["../src/logs.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,KAAK,EAEV,cAAc,EACd,iBAAiB,EAEjB,eAAe,EACf,0BAA0B,EAC3B,MAAM,YAAY,CAAC;AAEpB;;;;GAIG;AACH,wBAAsB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC,CAEzE;AAED;;;;;;;;GAQG;AACH,wBAAsB,yBAAyB,CAC7C,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CASxB;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAsB,gBAAgB,CACpC,eAAe,EAAE,MAAM,EACvB,OAAO,CAAC,EAAE,iBAAiB,GAC1B,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,CA0BhC;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,cAAc,qCAEjD;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,cAAc;;;;;;;;qBA7BQ,CAAC;uBAC9C,CAAH;;iBAEoC,CAAC;aAEtC,CAAA;;;;;;;;;;cAgBW,CAAC;aAClB,CAAC;;;;;;;EASA;AAMD;;;;;;;;;;GAUG;AACH,wBAAsB,cAAc,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAiB3E;AAiJD;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAsB,iBAAiB,CACrC,eAAe,EAAE,MAAM,GACtB,OAAO,CAAC,eAAe,CAAC,CAoE1B;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AACH,wBAAsB,mBAAmB,CACvC,eAAe,EAAE,MAAM,EACvB,OAAO,CAAC,EAAE,0BAA0B,GACnC,OAAO,CAAC,eAAe,CAAC,CAqC1B"}
package/dist/logs.js CHANGED
@@ -1,5 +1,7 @@
1
1
  /**
2
2
  * Klados log utilities for testing
3
+ *
4
+ * Includes tree-based traversal for multi-step workflows and scatter/gather operations.
3
5
  */
4
6
  import { apiRequest, sleep } from './client.js';
5
7
  /**
@@ -89,4 +91,307 @@ export function getLogMessages(log) {
89
91
  export function getLogEntry(log) {
90
92
  return log.properties.log_data.entry;
91
93
  }
94
+ // =============================================================================
95
+ // Log Tree Traversal
96
+ // =============================================================================
97
+ /**
98
+ * Get children of a log by querying for outgoing sent_to relationships
99
+ *
100
+ * In the Rhiza log tree:
101
+ * - Parents have `sent_to` outgoing relationships pointing to children
102
+ * - Children have `received_from` outgoing relationships pointing to parents
103
+ * - We use `sent_to` for traversal since it's an outgoing relationship (no indexing lag)
104
+ *
105
+ * @param logEntityId - Log entity ID to find children of
106
+ * @returns Array of child log entity IDs
107
+ */
108
+ export async function getLogChildren(logEntityId) {
109
+ try {
110
+ const entity = await apiRequest('GET', `/entities/${logEntityId}`);
111
+ // Look for outgoing sent_to relationships
112
+ // (this log has sent_to pointing to its children)
113
+ const childIds = entity.relationships
114
+ ?.filter((r) => r.predicate === 'sent_to' && r.direction === 'outgoing')
115
+ .map((r) => r.peer) ?? [];
116
+ return childIds;
117
+ }
118
+ catch {
119
+ return [];
120
+ }
121
+ }
122
+ /**
123
+ * Calculate expected children count from handoffs
124
+ *
125
+ * The testing package uses handoff types: 'invoke' | 'scatter' | 'complete' | 'error' | 'none'
126
+ * - 'invoke': Creates 1 child (pass operation)
127
+ * - 'scatter': Creates N children (tracked via job_id, not invocations array in testing types)
128
+ * - 'complete': No children (workflow done)
129
+ * - 'error': No children (error state)
130
+ * - 'none': No children (no handoff)
131
+ *
132
+ * @param log - Log entry to analyze
133
+ * @returns Number of expected children
134
+ */
135
+ function getExpectedChildrenCount(log) {
136
+ const entry = log.properties.log_data.entry;
137
+ const handoffs = entry.handoffs ?? [];
138
+ if (handoffs.length === 0) {
139
+ return 0; // No handoffs = leaf node
140
+ }
141
+ let total = 0;
142
+ for (const handoff of handoffs) {
143
+ if (handoff.type === 'invoke') {
144
+ // Invoke/pass creates 1 child
145
+ total += 1;
146
+ }
147
+ else if (handoff.type === 'scatter') {
148
+ // Scatter creates N children
149
+ // In the testing types, we don't have invocations array,
150
+ // so we rely on discovering children via relationships
151
+ // For now, mark as expecting at least 1 child
152
+ total += 1; // Will discover actual count via relationships
153
+ }
154
+ // 'complete', 'error', 'none' = 0 children
155
+ }
156
+ return total;
157
+ }
158
+ /**
159
+ * Build a log tree node recursively
160
+ *
161
+ * @param logEntityId - Entity ID of the log
162
+ * @param logsMap - Map to collect all discovered logs
163
+ * @param visited - Set of visited log IDs to prevent cycles
164
+ */
165
+ async function buildTreeNode(logEntityId, logsMap, visited) {
166
+ if (visited.has(logEntityId)) {
167
+ // Prevent infinite loops on malformed data
168
+ const existingLog = logsMap.get(logEntityId);
169
+ if (existingLog) {
170
+ return {
171
+ log: existingLog,
172
+ children: [],
173
+ isLeaf: true,
174
+ isTerminal: existingLog.properties.status === 'done' ||
175
+ existingLog.properties.status === 'error',
176
+ expectedChildren: 0,
177
+ };
178
+ }
179
+ return null;
180
+ }
181
+ visited.add(logEntityId);
182
+ // Fetch the log entry
183
+ let log;
184
+ try {
185
+ log = await getKladosLog(logEntityId);
186
+ logsMap.set(logEntityId, log);
187
+ }
188
+ catch {
189
+ // Log doesn't exist yet or fetch failed
190
+ return null;
191
+ }
192
+ const isTerminal = log.properties.status === 'done' || log.properties.status === 'error';
193
+ const expectedChildren = getExpectedChildrenCount(log);
194
+ // Find children via incoming relationships
195
+ const childIds = await getLogChildren(logEntityId);
196
+ // Recursively build child nodes
197
+ const children = [];
198
+ for (const childId of childIds) {
199
+ const childNode = await buildTreeNode(childId, logsMap, visited);
200
+ if (childNode) {
201
+ children.push(childNode);
202
+ }
203
+ }
204
+ // A node is a leaf if it's terminal AND has no expected children
205
+ // OR if it has error status (errors stop the branch)
206
+ const isLeaf = log.properties.status === 'error' ||
207
+ (isTerminal && expectedChildren === 0);
208
+ return {
209
+ log,
210
+ children,
211
+ isLeaf,
212
+ isTerminal,
213
+ expectedChildren,
214
+ };
215
+ }
216
+ /**
217
+ * Collect all leaf nodes from a tree
218
+ */
219
+ function collectLeaves(node) {
220
+ if (node.children.length === 0) {
221
+ return [node];
222
+ }
223
+ return node.children.flatMap(collectLeaves);
224
+ }
225
+ /**
226
+ * Check if all expected children have been discovered in the tree
227
+ *
228
+ * For scatter operations, we can't know the exact count from the testing types,
229
+ * so we check if we have at least the minimum expected and all discovered children
230
+ * are themselves complete.
231
+ */
232
+ function checkAllChildrenDiscovered(node) {
233
+ // If node is running, children may not exist yet
234
+ if (!node.isTerminal) {
235
+ return true; // Can't verify yet, assume OK for now
236
+ }
237
+ // If we expect children but have none, not complete
238
+ if (node.expectedChildren > 0 && node.children.length === 0) {
239
+ return false;
240
+ }
241
+ // Recursively check all children
242
+ return node.children.every(checkAllChildrenDiscovered);
243
+ }
244
+ /**
245
+ * Build a snapshot of the workflow log tree
246
+ *
247
+ * This traverses the log tree starting from the first_log relationship
248
+ * on the job collection, following incoming received_from relationships
249
+ * to discover all logs in the workflow.
250
+ *
251
+ * @example
252
+ * ```typescript
253
+ * const tree = await buildWorkflowTree(jobCollectionId);
254
+ *
255
+ * if (tree.isComplete) {
256
+ * console.log('Workflow finished with', tree.logs.size, 'logs');
257
+ * if (tree.hasErrors) {
258
+ * console.log('Errors:', tree.errors);
259
+ * }
260
+ * }
261
+ * ```
262
+ *
263
+ * @param jobCollectionId - Job collection ID
264
+ * @returns Current state of the workflow log tree
265
+ */
266
+ export async function buildWorkflowTree(jobCollectionId) {
267
+ const logsMap = new Map();
268
+ const visited = new Set();
269
+ // Find root via first_log relationship
270
+ const firstLogId = await getFirstLogFromCollection(jobCollectionId);
271
+ if (!firstLogId) {
272
+ return {
273
+ root: null,
274
+ logs: logsMap,
275
+ isComplete: false,
276
+ hasErrors: false,
277
+ leaves: [],
278
+ errors: [],
279
+ allChildrenDiscovered: false,
280
+ };
281
+ }
282
+ // Build tree starting from root
283
+ const root = await buildTreeNode(firstLogId, logsMap, visited);
284
+ if (!root) {
285
+ return {
286
+ root: null,
287
+ logs: logsMap,
288
+ isComplete: false,
289
+ hasErrors: false,
290
+ leaves: [],
291
+ errors: [],
292
+ allChildrenDiscovered: false,
293
+ };
294
+ }
295
+ // Collect leaves and analyze tree
296
+ const leaves = collectLeaves(root);
297
+ const allChildrenDiscovered = checkAllChildrenDiscovered(root);
298
+ // Workflow is complete when:
299
+ // 1. All leaves are terminal (done or error)
300
+ // 2. All expected children have been discovered
301
+ const allLeavesTerminal = leaves.every((leaf) => leaf.isTerminal);
302
+ const isComplete = allLeavesTerminal && allChildrenDiscovered;
303
+ // Collect errors
304
+ const errors = [];
305
+ for (const log of logsMap.values()) {
306
+ if (log.properties.status === 'error') {
307
+ const entry = log.properties.log_data.entry;
308
+ if (entry.error) {
309
+ errors.push({
310
+ logId: log.id,
311
+ kladosId: log.properties.klados_id,
312
+ error: entry.error,
313
+ });
314
+ }
315
+ }
316
+ }
317
+ return {
318
+ root,
319
+ logs: logsMap,
320
+ isComplete,
321
+ hasErrors: errors.length > 0,
322
+ leaves,
323
+ errors,
324
+ allChildrenDiscovered,
325
+ };
326
+ }
327
+ /**
328
+ * Wait for a workflow to complete by polling the log tree
329
+ *
330
+ * This function properly handles:
331
+ * - Multi-step workflows (A → B → C)
332
+ * - Scatter operations (A → [B1, B2, B3])
333
+ * - Nested scatters
334
+ * - Gather operations
335
+ * - Mixed success/error branches
336
+ *
337
+ * Unlike `waitForKladosLog` which only checks the first log, this function
338
+ * traverses the entire log tree and waits for ALL branches to complete.
339
+ *
340
+ * @example
341
+ * ```typescript
342
+ * // Wait for a scatter workflow to complete
343
+ * const tree = await waitForWorkflowTree(jobCollectionId, {
344
+ * timeout: 60000,
345
+ * pollInterval: 2000,
346
+ * });
347
+ *
348
+ * if (tree.isComplete) {
349
+ * console.log('All', tree.logs.size, 'logs completed');
350
+ * if (tree.hasErrors) {
351
+ * console.log('Some branches failed:', tree.errors);
352
+ * } else {
353
+ * console.log('Workflow succeeded!');
354
+ * }
355
+ * } else {
356
+ * console.log('Workflow timed out');
357
+ * }
358
+ * ```
359
+ *
360
+ * @param jobCollectionId - Job collection ID
361
+ * @param options - Wait options
362
+ * @returns Final state of the workflow log tree
363
+ */
364
+ export async function waitForWorkflowTree(jobCollectionId, options) {
365
+ const timeout = options?.timeout ?? 30000;
366
+ const pollInterval = options?.pollInterval ?? 2000;
367
+ const startTime = Date.now();
368
+ let lastTree = {
369
+ root: null,
370
+ logs: new Map(),
371
+ isComplete: false,
372
+ hasErrors: false,
373
+ leaves: [],
374
+ errors: [],
375
+ allChildrenDiscovered: false,
376
+ };
377
+ while (Date.now() - startTime < timeout) {
378
+ try {
379
+ const tree = await buildWorkflowTree(jobCollectionId);
380
+ lastTree = tree;
381
+ // Call optional progress callback
382
+ if (options?.onPoll) {
383
+ options.onPoll(tree, Date.now() - startTime);
384
+ }
385
+ if (tree.isComplete) {
386
+ return tree;
387
+ }
388
+ }
389
+ catch {
390
+ // Ignore errors during polling, just retry
391
+ }
392
+ await sleep(pollInterval);
393
+ }
394
+ // Timeout - return last known state
395
+ return lastTree;
396
+ }
92
397
  //# sourceMappingURL=logs.js.map
package/dist/logs.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"logs.js","sourceRoot":"","sources":["../src/logs.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAGhD;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,KAAa;IAC9C,OAAO,UAAU,CAAiB,KAAK,EAAE,aAAa,KAAK,EAAE,CAAC,CAAC;AACjE,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,yBAAyB,CAC7C,YAAoB;IAEpB,MAAM,UAAU,GAAG,MAAM,UAAU,CAAS,KAAK,EAAE,aAAa,YAAY,EAAE,CAAC,CAAC;IAEhF,kCAAkC;IAClC,MAAM,WAAW,GAAG,UAAU,CAAC,aAAa,EAAE,IAAI,CAChD,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,KAAK,WAAW,CACnC,CAAC;IAEF,OAAO,WAAW,EAAE,IAAI,IAAI,IAAI,CAAC;AACnC,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,eAAuB,EACvB,OAA2B;IAE3B,MAAM,OAAO,GAAG,OAAO,EAAE,OAAO,IAAI,KAAK,CAAC;IAC1C,MAAM,YAAY,GAAG,OAAO,EAAE,YAAY,IAAI,IAAI,CAAC;IACnD,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAE7B,OAAO,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,GAAG,OAAO,EAAE,CAAC;QACxC,IAAI,CAAC;YACH,oDAAoD;YACpD,MAAM,UAAU,GAAG,MAAM,yBAAyB,CAAC,eAAe,CAAC,CAAC;YAEpE,IAAI,UAAU,EAAE,CAAC;gBACf,MAAM,GAAG,GAAG,MAAM,YAAY,CAAC,UAAU,CAAC,CAAC;gBAC3C,0CAA0C;gBAC1C,IAAI,GAAG,CAAC,UAAU,CAAC,MAAM,KAAK,MAAM,IAAI,GAAG,CAAC,UAAU,CAAC,MAAM,KAAK,OAAO,EAAE,CAAC;oBAC1E,OAAO,GAAG,CAAC;gBACb,CAAC;gBACD,iDAAiD;YACnD,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,2CAA2C;QAC7C,CAAC;QAED,MAAM,KAAK,CAAC,YAAY,CAAC,CAAC;IAC5B,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,cAAc,CAAC,GAAmB;IAChD,OAAO,GAAG,CAAC,UAAU,CAAC,QAAQ,CAAC,QAAQ,CAAC;AAC1C,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,WAAW,CAAC,GAAmB;IAC7C,OAAO,GAAG,CAAC,UAAU,CAAC,QAAQ,CAAC,KAAK,CAAC;AACvC,CAAC"}
1
+ {"version":3,"file":"logs.js","sourceRoot":"","sources":["../src/logs.ts"],"names":[],"mappings":"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"}
package/dist/types.d.ts CHANGED
@@ -148,8 +148,8 @@ export interface InvokeKladosOptions {
148
148
  targetEntity?: string;
149
149
  /** Multiple entities to process (for cardinality: 'many') */
150
150
  targetEntities?: string[];
151
- /** Job collection for logs */
152
- jobCollection: string;
151
+ /** Job collection for logs (optional - API creates one if not provided) */
152
+ jobCollection?: string;
153
153
  /** Execute (true) or preview (false) */
154
154
  confirm?: boolean;
155
155
  /** Optional input data */
@@ -164,6 +164,59 @@ export interface WaitForLogOptions {
164
164
  /** Poll interval in milliseconds (default: 1000) */
165
165
  pollInterval?: number;
166
166
  }
167
+ /**
168
+ * A node in the workflow log tree
169
+ */
170
+ export interface LogTreeNode {
171
+ /** The log entry at this node */
172
+ log: KladosLogEntry;
173
+ /** Child nodes (logs that have this log in their from_logs) */
174
+ children: LogTreeNode[];
175
+ /** Whether this node is a leaf (no children expected) */
176
+ isLeaf: boolean;
177
+ /** Whether this log is terminal (done or error) */
178
+ isTerminal: boolean;
179
+ /** Number of expected children based on handoffs (may differ from actual) */
180
+ expectedChildren: number;
181
+ }
182
+ /**
183
+ * Result of building/traversing a workflow log tree
184
+ */
185
+ export interface WorkflowLogTree {
186
+ /** Root log node (found via first_log relationship) */
187
+ root: LogTreeNode | null;
188
+ /** All discovered logs indexed by entity ID */
189
+ logs: Map<string, KladosLogEntry>;
190
+ /** Whether the entire workflow has completed (all branches terminal) */
191
+ isComplete: boolean;
192
+ /** Whether any branch has errors */
193
+ hasErrors: boolean;
194
+ /** All leaf nodes in the tree */
195
+ leaves: LogTreeNode[];
196
+ /** All errors in the tree */
197
+ errors: Array<{
198
+ logId: string;
199
+ kladosId: string;
200
+ error: {
201
+ code: string;
202
+ message: string;
203
+ retryable: boolean;
204
+ };
205
+ }>;
206
+ /** Whether all expected children have been discovered */
207
+ allChildrenDiscovered: boolean;
208
+ }
209
+ /**
210
+ * Options for waiting for workflow tree completion
211
+ */
212
+ export interface WaitForWorkflowTreeOptions {
213
+ /** Maximum time to wait in milliseconds (default: 30000) */
214
+ timeout?: number;
215
+ /** Poll interval in milliseconds (default: 2000) */
216
+ pollInterval?: number;
217
+ /** Callback for each poll iteration (for debugging/logging) */
218
+ onPoll?: (tree: WorkflowLogTree, elapsed: number) => void;
219
+ }
167
220
  /**
168
221
  * Criteria for matching a log message
169
222
  */
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,204 @@
1
+ /**
2
+ * Rhiza workflow utilities for testing
3
+ *
4
+ * These utilities help test complete workflow compositions by:
5
+ * - Invoking rhiza workflows
6
+ * - Polling for workflow completion across multiple steps
7
+ * - Retrieving all logs from a workflow execution
8
+ */
9
+ import type { KladosLogEntry, WaitForLogOptions } from './types.js';
10
+ /**
11
+ * Options for invoking a rhiza workflow
12
+ */
13
+ export interface InvokeRhizaOptions {
14
+ /** Rhiza ID to invoke */
15
+ rhizaId: string;
16
+ /** Collection for permission scope (required) */
17
+ targetCollection: string;
18
+ /** Single entity to process (for entry klados with cardinality: 'one') */
19
+ targetEntity?: string;
20
+ /** Multiple entities to process (for entry klados with cardinality: 'many') */
21
+ targetEntities?: string[];
22
+ /** Job collection for logs (optional - API creates one if not provided) */
23
+ jobCollection?: string;
24
+ /** Execute (true) or preview (false) */
25
+ confirm?: boolean;
26
+ /** Optional input data passed to entry klados */
27
+ input?: Record<string, unknown>;
28
+ }
29
+ /**
30
+ * Result of invoking a rhiza workflow
31
+ */
32
+ export interface InvokeRhizaResult {
33
+ status: 'started' | 'rejected' | 'pending_confirmation';
34
+ job_id?: string;
35
+ job_collection?: string;
36
+ rhiza_id?: string;
37
+ error?: string;
38
+ message?: string;
39
+ }
40
+ /**
41
+ * Result of waiting for workflow completion
42
+ */
43
+ export interface WorkflowCompletionResult {
44
+ /** Overall workflow status */
45
+ status: 'done' | 'error' | 'timeout';
46
+ /** All klados log entries from the workflow */
47
+ logs: KladosLogEntry[];
48
+ /** Final output entity IDs (from last step) */
49
+ finalOutputs: string[];
50
+ /** Error message if status is 'error' */
51
+ error?: string;
52
+ }
53
+ /**
54
+ * Options for creating a rhiza entity
55
+ *
56
+ * Uses step-based flow format where:
57
+ * - entry is a step name (string)
58
+ * - flow keys are step names
59
+ * - each step has { klados: { pi: string }, then: ThenSpec }
60
+ * - ThenSpec targets are step names (strings)
61
+ */
62
+ export interface CreateRhizaOptions {
63
+ /** Display label for the rhiza */
64
+ label: string;
65
+ /** Description of what this workflow does */
66
+ description?: string;
67
+ /** Version string */
68
+ version: string;
69
+ /** Entry step name (first step in workflow) */
70
+ entry: string;
71
+ /** Flow definition - maps step names to their klados and handoff specs */
72
+ flow: Record<string, FlowStep>;
73
+ /** Collection to store the rhiza entity */
74
+ collectionId: string;
75
+ }
76
+ /**
77
+ * A step in the workflow flow definition
78
+ */
79
+ export interface FlowStep {
80
+ /** Which klados to invoke for this step */
81
+ klados: {
82
+ pi: string;
83
+ type?: string;
84
+ };
85
+ /** What happens after this step completes */
86
+ then: ThenSpec;
87
+ }
88
+ /**
89
+ * Handoff specification for a workflow step
90
+ * Targets are step names (strings), not klados IDs
91
+ */
92
+ export type ThenSpec = {
93
+ done: true;
94
+ } | {
95
+ pass: string;
96
+ route?: unknown[];
97
+ } | {
98
+ scatter: string;
99
+ route?: unknown[];
100
+ } | {
101
+ gather: string;
102
+ route?: unknown[];
103
+ };
104
+ /**
105
+ * Invoke a rhiza workflow
106
+ *
107
+ * @example
108
+ * ```typescript
109
+ * const result = await invokeRhiza({
110
+ * rhizaId: 'rhiza_abc123',
111
+ * targetEntity: entity.id,
112
+ * targetCollection: collection.id,
113
+ * jobCollection: jobCollection.id,
114
+ * confirm: true,
115
+ * });
116
+ *
117
+ * if (result.status === 'started') {
118
+ * console.log('Workflow started:', result.job_id);
119
+ * }
120
+ * ```
121
+ *
122
+ * @param options - Invocation options
123
+ * @returns The invocation result
124
+ */
125
+ export declare function invokeRhiza(options: InvokeRhizaOptions): Promise<InvokeRhizaResult>;
126
+ /**
127
+ * Create a rhiza workflow entity on the Arke network
128
+ *
129
+ * Uses step-based format where step names are the flow keys
130
+ * and the same klados can be used in multiple steps.
131
+ *
132
+ * @example
133
+ * ```typescript
134
+ * const rhiza = await createRhiza({
135
+ * label: 'Stamp Chain',
136
+ * version: '2.0',
137
+ * entry: 'first_stamp',
138
+ * flow: {
139
+ * 'first_stamp': { klados: { pi: 'klados_stamp' }, then: { pass: 'second_stamp' } },
140
+ * 'second_stamp': { klados: { pi: 'klados_stamp' }, then: { done: true } },
141
+ * },
142
+ * collectionId: collection.id,
143
+ * });
144
+ * ```
145
+ *
146
+ * @param options - Rhiza creation options
147
+ * @returns The created rhiza entity
148
+ */
149
+ export declare function createRhiza(options: CreateRhizaOptions): Promise<{
150
+ id: string;
151
+ }>;
152
+ /**
153
+ * Get all klados log entities from a job collection
154
+ *
155
+ * Queries the collection for all klados_log type entities.
156
+ * All workflow logs are stored in the same job collection.
157
+ *
158
+ * @param jobCollectionId - Job collection ID
159
+ * @returns Array of klados log entries
160
+ */
161
+ export declare function getWorkflowLogs(jobCollectionId: string): Promise<KladosLogEntry[]>;
162
+ /**
163
+ * Wait for a rhiza workflow to complete
164
+ *
165
+ * Polls the job collection until all logs are in terminal state (done or error).
166
+ * For simple workflows, this waits for the expected number of steps.
167
+ * For scatter workflows, this waits for all scattered invocations plus gather.
168
+ *
169
+ * @example
170
+ * ```typescript
171
+ * const result = await waitForWorkflowCompletion(jobCollection.id, {
172
+ * timeout: 60000,
173
+ * pollInterval: 2000,
174
+ * expectedSteps: 2, // For a 2-step chain
175
+ * });
176
+ *
177
+ * if (result.status === 'done') {
178
+ * console.log('Workflow completed with', result.logs.length, 'steps');
179
+ * }
180
+ * ```
181
+ *
182
+ * @param jobCollectionId - Job collection ID
183
+ * @param options - Wait options
184
+ * @returns Workflow completion result
185
+ */
186
+ export declare function waitForWorkflowCompletion(jobCollectionId: string, options?: WaitForLogOptions & {
187
+ expectedSteps?: number;
188
+ }): Promise<WorkflowCompletionResult>;
189
+ /**
190
+ * Assert that a workflow completed successfully with the expected number of steps
191
+ *
192
+ * @param result - Workflow completion result
193
+ * @param expectedSteps - Expected number of klados steps
194
+ * @throws Error if workflow failed or wrong number of steps
195
+ */
196
+ export declare function assertWorkflowCompleted(result: WorkflowCompletionResult, expectedSteps?: number): void;
197
+ /**
198
+ * Assert that logs show the expected workflow path (klados execution order)
199
+ *
200
+ * @param logs - Array of klados log entries
201
+ * @param expectedPath - Expected klados IDs in execution order
202
+ */
203
+ export declare function assertWorkflowPath(logs: KladosLogEntry[], expectedPath: string[]): void;
204
+ //# sourceMappingURL=workflows.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workflows.d.ts","sourceRoot":"","sources":["../src/workflows.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,KAAK,EAAE,cAAc,EAAE,iBAAiB,EAAU,MAAM,YAAY,CAAC;AAM5E;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,yBAAyB;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,iDAAiD;IACjD,gBAAgB,EAAE,MAAM,CAAC;IACzB,0EAA0E;IAC1E,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,+EAA+E;IAC/E,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,2EAA2E;IAC3E,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,wCAAwC;IACxC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,iDAAiD;IACjD,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACjC;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,SAAS,GAAG,UAAU,GAAG,sBAAsB,CAAC;IACxD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,wBAAwB;IACvC,8BAA8B;IAC9B,MAAM,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS,CAAC;IACrC,+CAA+C;IAC/C,IAAI,EAAE,cAAc,EAAE,CAAC;IACvB,+CAA+C;IAC/C,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,yCAAyC;IACzC,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,kBAAkB;IACjC,kCAAkC;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,6CAA6C;IAC7C,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,qBAAqB;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,+CAA+C;IAC/C,KAAK,EAAE,MAAM,CAAC;IACd,0EAA0E;IAC1E,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IAC/B,2CAA2C;IAC3C,YAAY,EAAE,MAAM,CAAC;CACtB;AAED;;GAEG;AACH,MAAM,WAAW,QAAQ;IACvB,2CAA2C;IAC3C,MAAM,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACtC,6CAA6C;IAC7C,IAAI,EAAE,QAAQ,CAAC;CAChB;AAED;;;GAGG;AACH,MAAM,MAAM,QAAQ,GAChB;IAAE,IAAI,EAAE,IAAI,CAAA;CAAE,GACd;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,OAAO,EAAE,CAAA;CAAE,GACnC;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,OAAO,EAAE,CAAA;CAAE,GACtC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,OAAO,EAAE,CAAA;CAAE,CAAC;AAM1C;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAsB,WAAW,CAC/B,OAAO,EAAE,kBAAkB,GAC1B,OAAO,CAAC,iBAAiB,CAAC,CA2B5B;AAMD;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAsB,WAAW,CAC/B,OAAO,EAAE,kBAAkB,GAC1B,OAAO,CAAC;IAAE,EAAE,EAAE,MAAM,CAAA;CAAE,CAAC,CAsBzB;AAMD;;;;;;;;GAQG;AACH,wBAAsB,eAAe,CACnC,eAAe,EAAE,MAAM,GACtB,OAAO,CAAC,cAAc,EAAE,CAAC,CAyB3B;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAsB,yBAAyB,CAC7C,eAAe,EAAE,MAAM,EACvB,OAAO,CAAC,EAAE,iBAAiB,GAAG;IAAE,aAAa,CAAC,EAAE,MAAM,CAAA;CAAE,GACvD,OAAO,CAAC,wBAAwB,CAAC,CAyEnC;AAMD;;;;;;GAMG;AACH,wBAAgB,uBAAuB,CACrC,MAAM,EAAE,wBAAwB,EAChC,aAAa,CAAC,EAAE,MAAM,GACrB,IAAI,CAiBN;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,cAAc,EAAE,EACtB,YAAY,EAAE,MAAM,EAAE,GACrB,IAAI,CAqBN"}
@@ -0,0 +1,256 @@
1
+ /**
2
+ * Rhiza workflow utilities for testing
3
+ *
4
+ * These utilities help test complete workflow compositions by:
5
+ * - Invoking rhiza workflows
6
+ * - Polling for workflow completion across multiple steps
7
+ * - Retrieving all logs from a workflow execution
8
+ */
9
+ import { apiRequest, sleep } from './client.js';
10
+ // =============================================================================
11
+ // Rhiza Invocation
12
+ // =============================================================================
13
+ /**
14
+ * Invoke a rhiza workflow
15
+ *
16
+ * @example
17
+ * ```typescript
18
+ * const result = await invokeRhiza({
19
+ * rhizaId: 'rhiza_abc123',
20
+ * targetEntity: entity.id,
21
+ * targetCollection: collection.id,
22
+ * jobCollection: jobCollection.id,
23
+ * confirm: true,
24
+ * });
25
+ *
26
+ * if (result.status === 'started') {
27
+ * console.log('Workflow started:', result.job_id);
28
+ * }
29
+ * ```
30
+ *
31
+ * @param options - Invocation options
32
+ * @returns The invocation result
33
+ */
34
+ export async function invokeRhiza(options) {
35
+ const body = {
36
+ target_collection: options.targetCollection,
37
+ confirm: options.confirm ?? true,
38
+ };
39
+ if (options.jobCollection) {
40
+ body.job_collection = options.jobCollection;
41
+ }
42
+ if (options.targetEntity) {
43
+ body.target_entity = options.targetEntity;
44
+ }
45
+ if (options.targetEntities) {
46
+ body.target_entities = options.targetEntities;
47
+ }
48
+ if (options.input) {
49
+ body.input = options.input;
50
+ }
51
+ return apiRequest('POST', `/rhizai/${options.rhizaId}/invoke`, body);
52
+ }
53
+ // =============================================================================
54
+ // Rhiza Creation
55
+ // =============================================================================
56
+ /**
57
+ * Create a rhiza workflow entity on the Arke network
58
+ *
59
+ * Uses step-based format where step names are the flow keys
60
+ * and the same klados can be used in multiple steps.
61
+ *
62
+ * @example
63
+ * ```typescript
64
+ * const rhiza = await createRhiza({
65
+ * label: 'Stamp Chain',
66
+ * version: '2.0',
67
+ * entry: 'first_stamp',
68
+ * flow: {
69
+ * 'first_stamp': { klados: { pi: 'klados_stamp' }, then: { pass: 'second_stamp' } },
70
+ * 'second_stamp': { klados: { pi: 'klados_stamp' }, then: { done: true } },
71
+ * },
72
+ * collectionId: collection.id,
73
+ * });
74
+ * ```
75
+ *
76
+ * @param options - Rhiza creation options
77
+ * @returns The created rhiza entity
78
+ */
79
+ export async function createRhiza(options) {
80
+ const properties = {
81
+ label: options.label,
82
+ version: options.version,
83
+ status: 'active',
84
+ // Entry is now a step name (string), not an EntityRef
85
+ entry: options.entry,
86
+ // Flow is passed through directly - already in the correct format
87
+ flow: options.flow,
88
+ };
89
+ if (options.description) {
90
+ properties.description = options.description;
91
+ }
92
+ const result = await apiRequest('POST', '/entities', {
93
+ type: 'rhiza',
94
+ properties,
95
+ collection_id: options.collectionId,
96
+ });
97
+ return result;
98
+ }
99
+ // =============================================================================
100
+ // Workflow Logs
101
+ // =============================================================================
102
+ /**
103
+ * Get all klados log entities from a job collection
104
+ *
105
+ * Queries the collection for all klados_log type entities.
106
+ * All workflow logs are stored in the same job collection.
107
+ *
108
+ * @param jobCollectionId - Job collection ID
109
+ * @returns Array of klados log entries
110
+ */
111
+ export async function getWorkflowLogs(jobCollectionId) {
112
+ // Query collection for all klados_log entities
113
+ const response = await apiRequest('GET', `/collections/${jobCollectionId}/entities?type=klados_log`);
114
+ if (!response.entities?.length) {
115
+ return [];
116
+ }
117
+ // Fetch full entity details for each log
118
+ const logs = [];
119
+ for (const entity of response.entities) {
120
+ try {
121
+ const log = await apiRequest('GET', `/entities/${entity.pi}`);
122
+ logs.push(log);
123
+ }
124
+ catch {
125
+ // Log may not exist yet or fetch failed, skip
126
+ }
127
+ }
128
+ return logs;
129
+ }
130
+ /**
131
+ * Wait for a rhiza workflow to complete
132
+ *
133
+ * Polls the job collection until all logs are in terminal state (done or error).
134
+ * For simple workflows, this waits for the expected number of steps.
135
+ * For scatter workflows, this waits for all scattered invocations plus gather.
136
+ *
137
+ * @example
138
+ * ```typescript
139
+ * const result = await waitForWorkflowCompletion(jobCollection.id, {
140
+ * timeout: 60000,
141
+ * pollInterval: 2000,
142
+ * expectedSteps: 2, // For a 2-step chain
143
+ * });
144
+ *
145
+ * if (result.status === 'done') {
146
+ * console.log('Workflow completed with', result.logs.length, 'steps');
147
+ * }
148
+ * ```
149
+ *
150
+ * @param jobCollectionId - Job collection ID
151
+ * @param options - Wait options
152
+ * @returns Workflow completion result
153
+ */
154
+ export async function waitForWorkflowCompletion(jobCollectionId, options) {
155
+ const timeout = options?.timeout ?? 30000;
156
+ const pollInterval = options?.pollInterval ?? 2000;
157
+ const expectedSteps = options?.expectedSteps;
158
+ const startTime = Date.now();
159
+ let lastLogs = [];
160
+ while (Date.now() - startTime < timeout) {
161
+ try {
162
+ const logs = await getWorkflowLogs(jobCollectionId);
163
+ lastLogs = logs;
164
+ // Check if we have any logs
165
+ if (logs.length === 0) {
166
+ await sleep(pollInterval);
167
+ continue;
168
+ }
169
+ // Check if all logs are in terminal state
170
+ const allTerminal = logs.every((log) => log.properties.status === 'done' || log.properties.status === 'error');
171
+ // Check if we have the expected number of steps (if specified)
172
+ const hasExpectedSteps = expectedSteps
173
+ ? logs.length >= expectedSteps
174
+ : true;
175
+ if (allTerminal && hasExpectedSteps) {
176
+ // Check if any log has error status
177
+ const hasError = logs.some((log) => log.properties.status === 'error');
178
+ // Get final outputs from the last step (by completion time)
179
+ const sortedLogs = [...logs].sort((a, b) => {
180
+ const aTime = a.properties.log_data.entry.completed_at ?? '';
181
+ const bTime = b.properties.log_data.entry.completed_at ?? '';
182
+ return aTime.localeCompare(bTime);
183
+ });
184
+ const lastLog = sortedLogs[sortedLogs.length - 1];
185
+ const finalOutputs = lastLog?.properties.log_data.entry.handoffs
186
+ ?.filter((h) => h.type === 'complete' || h.type === 'invoke')
187
+ .flatMap(() => []) ?? [];
188
+ return {
189
+ status: hasError ? 'error' : 'done',
190
+ logs,
191
+ finalOutputs,
192
+ error: hasError
193
+ ? logs.find((l) => l.properties.status === 'error')?.properties
194
+ .log_data.entry.error?.message
195
+ : undefined,
196
+ };
197
+ }
198
+ }
199
+ catch {
200
+ // Ignore errors during polling, just retry
201
+ }
202
+ await sleep(pollInterval);
203
+ }
204
+ // Timeout
205
+ return {
206
+ status: 'timeout',
207
+ logs: lastLogs,
208
+ finalOutputs: [],
209
+ error: `Workflow did not complete within ${timeout}ms`,
210
+ };
211
+ }
212
+ // =============================================================================
213
+ // Assertions
214
+ // =============================================================================
215
+ /**
216
+ * Assert that a workflow completed successfully with the expected number of steps
217
+ *
218
+ * @param result - Workflow completion result
219
+ * @param expectedSteps - Expected number of klados steps
220
+ * @throws Error if workflow failed or wrong number of steps
221
+ */
222
+ export function assertWorkflowCompleted(result, expectedSteps) {
223
+ if (result.status === 'timeout') {
224
+ throw new Error(`Workflow timed out. Got ${result.logs.length} logs, ` +
225
+ `statuses: ${result.logs.map((l) => l.properties.status).join(', ')}`);
226
+ }
227
+ if (result.status === 'error') {
228
+ throw new Error(`Workflow failed: ${result.error}`);
229
+ }
230
+ if (expectedSteps !== undefined && result.logs.length !== expectedSteps) {
231
+ throw new Error(`Expected ${expectedSteps} workflow steps, got ${result.logs.length}`);
232
+ }
233
+ }
234
+ /**
235
+ * Assert that logs show the expected workflow path (klados execution order)
236
+ *
237
+ * @param logs - Array of klados log entries
238
+ * @param expectedPath - Expected klados IDs in execution order
239
+ */
240
+ export function assertWorkflowPath(logs, expectedPath) {
241
+ // Sort by start time
242
+ const sortedLogs = [...logs].sort((a, b) => {
243
+ const aTime = a.properties.log_data.entry.started_at;
244
+ const bTime = b.properties.log_data.entry.started_at;
245
+ return aTime.localeCompare(bTime);
246
+ });
247
+ const actualPath = sortedLogs.map((l) => l.properties.klados_id);
248
+ const match = actualPath.length === expectedPath.length &&
249
+ actualPath.every((id, i) => id === expectedPath[i]);
250
+ if (!match) {
251
+ throw new Error(`Workflow path mismatch.\n` +
252
+ `Expected: ${expectedPath.join(' → ')}\n` +
253
+ `Actual: ${actualPath.join(' → ')}`);
254
+ }
255
+ }
256
+ //# sourceMappingURL=workflows.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workflows.js","sourceRoot":"","sources":["../src/workflows.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@arke-institute/klados-testing",
3
- "version": "0.1.2",
3
+ "version": "0.3.0",
4
4
  "description": "Test utilities for klados workers on the Arke network",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -21,7 +21,7 @@
21
21
  "clean": "rm -rf dist"
22
22
  },
23
23
  "peerDependencies": {
24
- "@arke-institute/sdk": "^2.9.0"
24
+ "@arke-institute/sdk": "^3.0.0"
25
25
  },
26
26
  "peerDependenciesMeta": {
27
27
  "@arke-institute/sdk": {
@@ -29,7 +29,7 @@
29
29
  }
30
30
  },
31
31
  "devDependencies": {
32
- "@arke-institute/sdk": "^2.9.0",
32
+ "@arke-institute/sdk": "^3.0.0",
33
33
  "typescript": "^5.7.2"
34
34
  },
35
35
  "keywords": [