@okf/ootils 1.39.2 → 1.40.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.
package/dist/node.d.mts CHANGED
@@ -3,6 +3,7 @@ import * as mongoose from 'mongoose';
3
3
  import mongoose__default, { Document, Types, Schema } from 'mongoose';
4
4
  import * as bullmq from 'bullmq';
5
5
  import { Queue } from 'bullmq/dist/esm/classes/queue';
6
+ import { FlowProducer } from 'bullmq/dist/esm/classes/flow-producer';
6
7
  import { Worker } from 'bullmq/dist/esm/classes/worker';
7
8
 
8
9
  declare const deleteVal: (data: any, valuePath: string) => any;
@@ -2082,7 +2083,7 @@ declare class RedisCacheConnector {
2082
2083
  * @param {string} [params.tenant] - Tenant (either a single tenant or an array of tenants for whom the config cache should be refreshed)
2083
2084
  * @static
2084
2085
  */
2085
- static loadTplsAndPlatformConfigsToCache({ tenant }?: string): Promise<void>;
2086
+ static loadTplsAndPlatformConfigsToCache({ tenant, env }?: string): Promise<void>;
2086
2087
  /**
2087
2088
  * @param {Object} options
2088
2089
  *
@@ -2592,6 +2593,100 @@ declare class BaseProducer {
2592
2593
  stop(): Promise<void>;
2593
2594
  }
2594
2595
 
2596
+ /**
2597
+ * BaseFlowProducer — the flow-equivalent of BaseProducer.
2598
+ *
2599
+ * A BullMQ Flow adds its parent + children jobs straight into each queue's
2600
+ * Redis keys WITHOUT going through a Queue instance. That means flow nodes do
2601
+ * NOT inherit their queue's `defaultJobOptions` the way `BaseProducer` jobs do
2602
+ * (BaseProducer gets them for free via `new Queue(id, queueConfig)`). Left
2603
+ * unhandled, options like removeOnComplete/removeOnFail are never applied and
2604
+ * completed/failed jobs accumulate unbounded.
2605
+ *
2606
+ * This base centralises the one thing that must happen for every flow: each
2607
+ * node's `opts` is layered as `{ ...queueDefaultJobOptions, ...nodeOpts }`,
2608
+ * mirroring exactly how BullMQ layers defaultJobOptions under per-`add` opts
2609
+ * for normal queues. So subclasses declare ONLY structure + job-specific opts
2610
+ * (e.g. failParentOnFailure); retention and other defaults flow from the same
2611
+ * GLOBAL_BULLMQ_CONFIG that the queues/workers already read — single source of
2612
+ * truth, no per-call-site restatement.
2613
+ *
2614
+ * Construction takes the SAME config objects (entries of GET_GLOBAL_BULLMQ_CONFIG)
2615
+ * that BaseProducer/BaseWorker consume, so a flow is configured declaratively
2616
+ * alongside its queues.
2617
+ *
2618
+ * @param {Object} params
2619
+ * @param {Object} params.parentConfig
2620
+ * The GLOBAL_BULLMQ_CONFIG entry for the parent queue (has .id, .queueConfig).
2621
+ * @param {Object} params.childConfigs
2622
+ * Map keyed by an arbitrary childKey →
2623
+ * the GLOBAL_BULLMQ_CONFIG entry for that
2624
+ * child queue. Subclasses reference a child
2625
+ * node's queue by this key, never by id.
2626
+ */
2627
+ declare class BaseFlowProducer {
2628
+ constructor({ parentConfig, childConfigs }: {
2629
+ parentConfig: any;
2630
+ childConfigs?: {} | undefined;
2631
+ });
2632
+ parentConfig: any;
2633
+ childConfigs: {};
2634
+ flow: FlowProducer;
2635
+ /**
2636
+ * Build & enqueue a flow declaratively.
2637
+ *
2638
+ * @param {Object} params
2639
+ * @param {string} [params.name] Parent job name.
2640
+ * @param {Object} params.parentData Parent job data.
2641
+ * @param {Object} [params.parentOpts] Per-node opts for the parent, layered
2642
+ * over the parent queue's defaults.
2643
+ * @param {Array} params.children One entry per child node:
2644
+ * @param {string} children[].childKey Key into childConfigs (which queue).
2645
+ * @param {string} [children[].name] Child job name.
2646
+ * @param {Object} children[].data Child job data.
2647
+ * @param {Object} [children[].opts] Job-specific opts (e.g.
2648
+ * failParentOnFailure); layered over
2649
+ * that child queue's defaults.
2650
+ * @returns {Promise<{ parentJobId, childJobIds }>}
2651
+ */
2652
+ addFlow({ name, parentData, parentOpts, children }: {
2653
+ name?: string | undefined;
2654
+ parentData: Object;
2655
+ parentOpts?: Object | undefined;
2656
+ children: any[];
2657
+ }): Promise<{
2658
+ parentJobId: any;
2659
+ childJobIds: any;
2660
+ }>;
2661
+ /**
2662
+ * Find the FIRST parent job in the given states whose data matches the
2663
+ * predicate — e.g. an in-flight lock check ("is a run already pending for
2664
+ * this tenant?"). Opens a short-lived Queue on the parent queue and closes
2665
+ * it before returning, so callers don't have to reach into config internals
2666
+ * to construct one themselves.
2667
+ *
2668
+ * Returns the first match or null. BullMQ can't filter by job.data
2669
+ * server-side, so this still fetches the in-flight set and scans in JS; the
2670
+ * contract is intentionally first-match (not a list) because that's the only
2671
+ * thing the lock-check use case needs.
2672
+ *
2673
+ * @param {Object} params
2674
+ * @param {string[]} params.states
2675
+ * Job states to scan, e.g. ["waiting", "active", "delayed"].
2676
+ * @param {(data: any, job: any) => boolean} params.matchData
2677
+ * Required function; receives job.data (and the job). Without it there's
2678
+ * no meaningful "match", so this throws — returning an arbitrary in-flight
2679
+ * job would be a silent caller bug.
2680
+ * @returns {Promise<Object|null>} The first matching parent job, or null.
2681
+ */
2682
+ findParentJob({ states, matchData }: {
2683
+ states: string[];
2684
+ matchData: (data: any, job: any) => boolean;
2685
+ }): Promise<Object | null>;
2686
+ stop(): Promise<void>;
2687
+ #private;
2688
+ }
2689
+
2595
2690
  declare class BaseWorker {
2596
2691
  constructor(config: any);
2597
2692
  config: any;
@@ -2648,4 +2743,4 @@ declare function GET_GLOBAL_BULLMQ_CONFIG({ env, redisCredentials }: {
2648
2743
  };
2649
2744
  }): Object;
2650
2745
 
2651
- export { AIChatSchema, AnnosElasticSyncProducer, AnnotationSchema, BASE_BULLMQ_CONFIG, BaseProducer, BaseWorker, type BlockCapabilities, type BlockDef, BlockRegistry, CHUNKING_PRESETS, ChunksElasticSyncProducer, ELASTIC_MAPPING_PRESETS, ElasticSearchConnector, FILTER_IDS, GET_GLOBAL_BULLMQ_CONFIG, GeneratedEntitiesSchema, GeneratedTopicsSchema, MONGO_SCHEMA_PRESETS, MongoConnector, PlatformConfigsSchema, ProducerManager, RedisCacheConnector, SecretManagerConnector, TEMP_removeDuplicateFilters, TplSchema, UI_CONTENT, WorkerManager, _self_managed_buildAnnoHierarchyConfig, _self_managed_buildDocHierarchyConfig, _self_managed_getFixedAnnoRollupBlocks, _self_managed_getFixedAnnoTagBlock, autoGenFilterConfigsFromTpl, blockRegistry, buildFilterConfigurations, collectMarkIdsInOrder, compareAndGroupBlocks, deleteVal, extractAllBlocksFromTpl, extractAndOrganizeBlocks, genCleanCamelCaseId, genTagId, generateFilterKey, getAIChatModelByTenant, getAnnoFilterBucketKey, getAnnotationsModelByTenant, getDbByTenant, getFilterKeyForBlock, getGeneratedEntitiesModelByTenant, getGeneratedTopicsModelByTenant, getModelByTenant, getPlatformConfigsModelByTenant, getPlatformContextContent, getRollupPossibilities, getRoutePathToContentTypeLanding, getRoutePathToEditContent, getRoutePathToModerateContent, getRoutePathToMyContent, getRoutePathToPublishedContent, getRoutePathToReviewDashboard, getRoutePathToTCI, getRoutePathToTagCategoryLanding, getTplModelByTenant, getVal, isTplAnnotationEnabled, mergeAnnoDataIntoAnnotationsTags, parseSpecialConfigSyntax, plainTextToLexical, processAuthorAndCommonFilters, _recursExtractBlocks as recursivelyExtractBlocks, segrigateDocs, setVal, toArray };
2746
+ export { AIChatSchema, AnnosElasticSyncProducer, AnnotationSchema, BASE_BULLMQ_CONFIG, BaseFlowProducer, BaseProducer, BaseWorker, type BlockCapabilities, type BlockDef, BlockRegistry, CHUNKING_PRESETS, ChunksElasticSyncProducer, ELASTIC_MAPPING_PRESETS, ElasticSearchConnector, FILTER_IDS, GET_GLOBAL_BULLMQ_CONFIG, GeneratedEntitiesSchema, GeneratedTopicsSchema, MONGO_SCHEMA_PRESETS, MongoConnector, PlatformConfigsSchema, ProducerManager, RedisCacheConnector, SecretManagerConnector, TEMP_removeDuplicateFilters, TplSchema, UI_CONTENT, WorkerManager, _self_managed_buildAnnoHierarchyConfig, _self_managed_buildDocHierarchyConfig, _self_managed_getFixedAnnoRollupBlocks, _self_managed_getFixedAnnoTagBlock, autoGenFilterConfigsFromTpl, blockRegistry, buildFilterConfigurations, collectMarkIdsInOrder, compareAndGroupBlocks, deleteVal, extractAllBlocksFromTpl, extractAndOrganizeBlocks, genCleanCamelCaseId, genTagId, generateFilterKey, getAIChatModelByTenant, getAnnoFilterBucketKey, getAnnotationsModelByTenant, getDbByTenant, getFilterKeyForBlock, getGeneratedEntitiesModelByTenant, getGeneratedTopicsModelByTenant, getModelByTenant, getPlatformConfigsModelByTenant, getPlatformContextContent, getRollupPossibilities, getRoutePathToContentTypeLanding, getRoutePathToEditContent, getRoutePathToModerateContent, getRoutePathToMyContent, getRoutePathToPublishedContent, getRoutePathToReviewDashboard, getRoutePathToTCI, getRoutePathToTagCategoryLanding, getTplModelByTenant, getVal, isTplAnnotationEnabled, mergeAnnoDataIntoAnnotationsTags, parseSpecialConfigSyntax, plainTextToLexical, processAuthorAndCommonFilters, _recursExtractBlocks as recursivelyExtractBlocks, segrigateDocs, setVal, toArray };
package/dist/node.d.ts CHANGED
@@ -3,6 +3,7 @@ import * as mongoose from 'mongoose';
3
3
  import mongoose__default, { Document, Types, Schema } from 'mongoose';
4
4
  import * as bullmq from 'bullmq';
5
5
  import { Queue } from 'bullmq/dist/esm/classes/queue';
6
+ import { FlowProducer } from 'bullmq/dist/esm/classes/flow-producer';
6
7
  import { Worker } from 'bullmq/dist/esm/classes/worker';
7
8
 
8
9
  declare const deleteVal: (data: any, valuePath: string) => any;
@@ -2082,7 +2083,7 @@ declare class RedisCacheConnector {
2082
2083
  * @param {string} [params.tenant] - Tenant (either a single tenant or an array of tenants for whom the config cache should be refreshed)
2083
2084
  * @static
2084
2085
  */
2085
- static loadTplsAndPlatformConfigsToCache({ tenant }?: string): Promise<void>;
2086
+ static loadTplsAndPlatformConfigsToCache({ tenant, env }?: string): Promise<void>;
2086
2087
  /**
2087
2088
  * @param {Object} options
2088
2089
  *
@@ -2592,6 +2593,100 @@ declare class BaseProducer {
2592
2593
  stop(): Promise<void>;
2593
2594
  }
2594
2595
 
2596
+ /**
2597
+ * BaseFlowProducer — the flow-equivalent of BaseProducer.
2598
+ *
2599
+ * A BullMQ Flow adds its parent + children jobs straight into each queue's
2600
+ * Redis keys WITHOUT going through a Queue instance. That means flow nodes do
2601
+ * NOT inherit their queue's `defaultJobOptions` the way `BaseProducer` jobs do
2602
+ * (BaseProducer gets them for free via `new Queue(id, queueConfig)`). Left
2603
+ * unhandled, options like removeOnComplete/removeOnFail are never applied and
2604
+ * completed/failed jobs accumulate unbounded.
2605
+ *
2606
+ * This base centralises the one thing that must happen for every flow: each
2607
+ * node's `opts` is layered as `{ ...queueDefaultJobOptions, ...nodeOpts }`,
2608
+ * mirroring exactly how BullMQ layers defaultJobOptions under per-`add` opts
2609
+ * for normal queues. So subclasses declare ONLY structure + job-specific opts
2610
+ * (e.g. failParentOnFailure); retention and other defaults flow from the same
2611
+ * GLOBAL_BULLMQ_CONFIG that the queues/workers already read — single source of
2612
+ * truth, no per-call-site restatement.
2613
+ *
2614
+ * Construction takes the SAME config objects (entries of GET_GLOBAL_BULLMQ_CONFIG)
2615
+ * that BaseProducer/BaseWorker consume, so a flow is configured declaratively
2616
+ * alongside its queues.
2617
+ *
2618
+ * @param {Object} params
2619
+ * @param {Object} params.parentConfig
2620
+ * The GLOBAL_BULLMQ_CONFIG entry for the parent queue (has .id, .queueConfig).
2621
+ * @param {Object} params.childConfigs
2622
+ * Map keyed by an arbitrary childKey →
2623
+ * the GLOBAL_BULLMQ_CONFIG entry for that
2624
+ * child queue. Subclasses reference a child
2625
+ * node's queue by this key, never by id.
2626
+ */
2627
+ declare class BaseFlowProducer {
2628
+ constructor({ parentConfig, childConfigs }: {
2629
+ parentConfig: any;
2630
+ childConfigs?: {} | undefined;
2631
+ });
2632
+ parentConfig: any;
2633
+ childConfigs: {};
2634
+ flow: FlowProducer;
2635
+ /**
2636
+ * Build & enqueue a flow declaratively.
2637
+ *
2638
+ * @param {Object} params
2639
+ * @param {string} [params.name] Parent job name.
2640
+ * @param {Object} params.parentData Parent job data.
2641
+ * @param {Object} [params.parentOpts] Per-node opts for the parent, layered
2642
+ * over the parent queue's defaults.
2643
+ * @param {Array} params.children One entry per child node:
2644
+ * @param {string} children[].childKey Key into childConfigs (which queue).
2645
+ * @param {string} [children[].name] Child job name.
2646
+ * @param {Object} children[].data Child job data.
2647
+ * @param {Object} [children[].opts] Job-specific opts (e.g.
2648
+ * failParentOnFailure); layered over
2649
+ * that child queue's defaults.
2650
+ * @returns {Promise<{ parentJobId, childJobIds }>}
2651
+ */
2652
+ addFlow({ name, parentData, parentOpts, children }: {
2653
+ name?: string | undefined;
2654
+ parentData: Object;
2655
+ parentOpts?: Object | undefined;
2656
+ children: any[];
2657
+ }): Promise<{
2658
+ parentJobId: any;
2659
+ childJobIds: any;
2660
+ }>;
2661
+ /**
2662
+ * Find the FIRST parent job in the given states whose data matches the
2663
+ * predicate — e.g. an in-flight lock check ("is a run already pending for
2664
+ * this tenant?"). Opens a short-lived Queue on the parent queue and closes
2665
+ * it before returning, so callers don't have to reach into config internals
2666
+ * to construct one themselves.
2667
+ *
2668
+ * Returns the first match or null. BullMQ can't filter by job.data
2669
+ * server-side, so this still fetches the in-flight set and scans in JS; the
2670
+ * contract is intentionally first-match (not a list) because that's the only
2671
+ * thing the lock-check use case needs.
2672
+ *
2673
+ * @param {Object} params
2674
+ * @param {string[]} params.states
2675
+ * Job states to scan, e.g. ["waiting", "active", "delayed"].
2676
+ * @param {(data: any, job: any) => boolean} params.matchData
2677
+ * Required function; receives job.data (and the job). Without it there's
2678
+ * no meaningful "match", so this throws — returning an arbitrary in-flight
2679
+ * job would be a silent caller bug.
2680
+ * @returns {Promise<Object|null>} The first matching parent job, or null.
2681
+ */
2682
+ findParentJob({ states, matchData }: {
2683
+ states: string[];
2684
+ matchData: (data: any, job: any) => boolean;
2685
+ }): Promise<Object | null>;
2686
+ stop(): Promise<void>;
2687
+ #private;
2688
+ }
2689
+
2595
2690
  declare class BaseWorker {
2596
2691
  constructor(config: any);
2597
2692
  config: any;
@@ -2648,4 +2743,4 @@ declare function GET_GLOBAL_BULLMQ_CONFIG({ env, redisCredentials }: {
2648
2743
  };
2649
2744
  }): Object;
2650
2745
 
2651
- export { AIChatSchema, AnnosElasticSyncProducer, AnnotationSchema, BASE_BULLMQ_CONFIG, BaseProducer, BaseWorker, type BlockCapabilities, type BlockDef, BlockRegistry, CHUNKING_PRESETS, ChunksElasticSyncProducer, ELASTIC_MAPPING_PRESETS, ElasticSearchConnector, FILTER_IDS, GET_GLOBAL_BULLMQ_CONFIG, GeneratedEntitiesSchema, GeneratedTopicsSchema, MONGO_SCHEMA_PRESETS, MongoConnector, PlatformConfigsSchema, ProducerManager, RedisCacheConnector, SecretManagerConnector, TEMP_removeDuplicateFilters, TplSchema, UI_CONTENT, WorkerManager, _self_managed_buildAnnoHierarchyConfig, _self_managed_buildDocHierarchyConfig, _self_managed_getFixedAnnoRollupBlocks, _self_managed_getFixedAnnoTagBlock, autoGenFilterConfigsFromTpl, blockRegistry, buildFilterConfigurations, collectMarkIdsInOrder, compareAndGroupBlocks, deleteVal, extractAllBlocksFromTpl, extractAndOrganizeBlocks, genCleanCamelCaseId, genTagId, generateFilterKey, getAIChatModelByTenant, getAnnoFilterBucketKey, getAnnotationsModelByTenant, getDbByTenant, getFilterKeyForBlock, getGeneratedEntitiesModelByTenant, getGeneratedTopicsModelByTenant, getModelByTenant, getPlatformConfigsModelByTenant, getPlatformContextContent, getRollupPossibilities, getRoutePathToContentTypeLanding, getRoutePathToEditContent, getRoutePathToModerateContent, getRoutePathToMyContent, getRoutePathToPublishedContent, getRoutePathToReviewDashboard, getRoutePathToTCI, getRoutePathToTagCategoryLanding, getTplModelByTenant, getVal, isTplAnnotationEnabled, mergeAnnoDataIntoAnnotationsTags, parseSpecialConfigSyntax, plainTextToLexical, processAuthorAndCommonFilters, _recursExtractBlocks as recursivelyExtractBlocks, segrigateDocs, setVal, toArray };
2746
+ export { AIChatSchema, AnnosElasticSyncProducer, AnnotationSchema, BASE_BULLMQ_CONFIG, BaseFlowProducer, BaseProducer, BaseWorker, type BlockCapabilities, type BlockDef, BlockRegistry, CHUNKING_PRESETS, ChunksElasticSyncProducer, ELASTIC_MAPPING_PRESETS, ElasticSearchConnector, FILTER_IDS, GET_GLOBAL_BULLMQ_CONFIG, GeneratedEntitiesSchema, GeneratedTopicsSchema, MONGO_SCHEMA_PRESETS, MongoConnector, PlatformConfigsSchema, ProducerManager, RedisCacheConnector, SecretManagerConnector, TEMP_removeDuplicateFilters, TplSchema, UI_CONTENT, WorkerManager, _self_managed_buildAnnoHierarchyConfig, _self_managed_buildDocHierarchyConfig, _self_managed_getFixedAnnoRollupBlocks, _self_managed_getFixedAnnoTagBlock, autoGenFilterConfigsFromTpl, blockRegistry, buildFilterConfigurations, collectMarkIdsInOrder, compareAndGroupBlocks, deleteVal, extractAllBlocksFromTpl, extractAndOrganizeBlocks, genCleanCamelCaseId, genTagId, generateFilterKey, getAIChatModelByTenant, getAnnoFilterBucketKey, getAnnotationsModelByTenant, getDbByTenant, getFilterKeyForBlock, getGeneratedEntitiesModelByTenant, getGeneratedTopicsModelByTenant, getModelByTenant, getPlatformConfigsModelByTenant, getPlatformContextContent, getRollupPossibilities, getRoutePathToContentTypeLanding, getRoutePathToEditContent, getRoutePathToModerateContent, getRoutePathToMyContent, getRoutePathToPublishedContent, getRoutePathToReviewDashboard, getRoutePathToTCI, getRoutePathToTagCategoryLanding, getTplModelByTenant, getVal, isTplAnnotationEnabled, mergeAnnoDataIntoAnnotationsTags, parseSpecialConfigSyntax, plainTextToLexical, processAuthorAndCommonFilters, _recursExtractBlocks as recursivelyExtractBlocks, segrigateDocs, setVal, toArray };
package/dist/node.js CHANGED
@@ -5,6 +5,9 @@ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
5
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
6
  var __getProtoOf = Object.getPrototypeOf;
7
7
  var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __typeError = (msg) => {
9
+ throw TypeError(msg);
10
+ };
8
11
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
9
12
  var __esm = (fn, res) => function __init() {
10
13
  return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
@@ -34,6 +37,9 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
34
37
  ));
35
38
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
36
39
  var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
40
+ var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg);
41
+ var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
42
+ var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "access private method"), method);
37
43
 
38
44
  // src/bullmq/GLOBAL_BULLMQ_CONFIG.js
39
45
  var GLOBAL_BULLMQ_CONFIG_exports = {};
@@ -1912,6 +1918,133 @@ var require_BaseProducer = __commonJS({
1912
1918
  }
1913
1919
  });
1914
1920
 
1921
+ // src/bullmq/BaseFlowProducer.js
1922
+ var require_BaseFlowProducer = __commonJS({
1923
+ "src/bullmq/BaseFlowProducer.js"(exports2, module2) {
1924
+ "use strict";
1925
+ var { FlowProducer, Queue } = require("bullmq");
1926
+ var _BaseFlowProducer_instances, mergeOpts_fn, childConfig_fn;
1927
+ var BaseFlowProducer2 = class {
1928
+ constructor({ parentConfig, childConfigs = {} }) {
1929
+ __privateAdd(this, _BaseFlowProducer_instances);
1930
+ if (!parentConfig) {
1931
+ throw new Error("BaseFlowProducer requires a parentConfig");
1932
+ }
1933
+ this.parentConfig = parentConfig;
1934
+ this.childConfigs = childConfigs;
1935
+ this.flow = new FlowProducer({
1936
+ connection: parentConfig.queueConfig.connection
1937
+ });
1938
+ }
1939
+ /**
1940
+ * Build & enqueue a flow declaratively.
1941
+ *
1942
+ * @param {Object} params
1943
+ * @param {string} [params.name] Parent job name.
1944
+ * @param {Object} params.parentData Parent job data.
1945
+ * @param {Object} [params.parentOpts] Per-node opts for the parent, layered
1946
+ * over the parent queue's defaults.
1947
+ * @param {Array} params.children One entry per child node:
1948
+ * @param {string} children[].childKey Key into childConfigs (which queue).
1949
+ * @param {string} [children[].name] Child job name.
1950
+ * @param {Object} children[].data Child job data.
1951
+ * @param {Object} [children[].opts] Job-specific opts (e.g.
1952
+ * failParentOnFailure); layered over
1953
+ * that child queue's defaults.
1954
+ * @returns {Promise<{ parentJobId, childJobIds }>}
1955
+ */
1956
+ async addFlow({ name, parentData, parentOpts = {}, children = [] }) {
1957
+ const flowJob = await this.flow.add({
1958
+ name,
1959
+ queueName: this.parentConfig.id,
1960
+ data: parentData,
1961
+ opts: __privateMethod(this, _BaseFlowProducer_instances, mergeOpts_fn).call(this, this.parentConfig, parentOpts),
1962
+ children: children.map((child) => {
1963
+ const childCfg = __privateMethod(this, _BaseFlowProducer_instances, childConfig_fn).call(this, child.childKey);
1964
+ return {
1965
+ name: child.name,
1966
+ queueName: childCfg.id,
1967
+ data: child.data,
1968
+ opts: __privateMethod(this, _BaseFlowProducer_instances, mergeOpts_fn).call(this, childCfg, child.opts)
1969
+ };
1970
+ })
1971
+ });
1972
+ const parentJobId = flowJob?.job?.id;
1973
+ const childJobIds = (flowJob?.children || []).map((c) => c?.job?.id).filter(Boolean);
1974
+ return { parentJobId, childJobIds };
1975
+ }
1976
+ /**
1977
+ * Find the FIRST parent job in the given states whose data matches the
1978
+ * predicate — e.g. an in-flight lock check ("is a run already pending for
1979
+ * this tenant?"). Opens a short-lived Queue on the parent queue and closes
1980
+ * it before returning, so callers don't have to reach into config internals
1981
+ * to construct one themselves.
1982
+ *
1983
+ * Returns the first match or null. BullMQ can't filter by job.data
1984
+ * server-side, so this still fetches the in-flight set and scans in JS; the
1985
+ * contract is intentionally first-match (not a list) because that's the only
1986
+ * thing the lock-check use case needs.
1987
+ *
1988
+ * @param {Object} params
1989
+ * @param {string[]} params.states
1990
+ * Job states to scan, e.g. ["waiting", "active", "delayed"].
1991
+ * @param {(data: any, job: any) => boolean} params.matchData
1992
+ * Required function; receives job.data (and the job). Without it there's
1993
+ * no meaningful "match", so this throws — returning an arbitrary in-flight
1994
+ * job would be a silent caller bug.
1995
+ * @returns {Promise<Object|null>} The first matching parent job, or null.
1996
+ */
1997
+ async findParentJob({ states, matchData }) {
1998
+ if (typeof matchData !== "function") {
1999
+ throw new Error("BaseFlowProducer.findParentJob requires a matchData function");
2000
+ }
2001
+ const parentQueue = new Queue(
2002
+ this.parentConfig.id,
2003
+ this.parentConfig.queueConfig
2004
+ );
2005
+ try {
2006
+ const jobs = await parentQueue.getJobs(states, 0, -1);
2007
+ return jobs.find((job) => matchData(job?.data, job)) || null;
2008
+ } finally {
2009
+ await parentQueue.close();
2010
+ }
2011
+ }
2012
+ async stop() {
2013
+ if (this.flow) {
2014
+ try {
2015
+ await this.flow.close();
2016
+ } catch (err) {
2017
+ console.warn(`[${this.constructor.name}] flow close failed: ${err.message}`);
2018
+ }
2019
+ }
2020
+ }
2021
+ };
2022
+ _BaseFlowProducer_instances = new WeakSet();
2023
+ /**
2024
+ * Layer a queue config's defaultJobOptions under per-node opts — identical
2025
+ * to how BullMQ merges defaultJobOptions under per-`add` opts for a Queue.
2026
+ * Config is the base; anything the node explicitly sets wins.
2027
+ */
2028
+ mergeOpts_fn = function(queueConfig, nodeOpts = {}) {
2029
+ const defaults = queueConfig?.queueConfig?.defaultJobOptions || {};
2030
+ return { ...defaults, ...nodeOpts };
2031
+ };
2032
+ /**
2033
+ * Resolve the GLOBAL_BULLMQ_CONFIG entry for a declared child key.
2034
+ */
2035
+ childConfig_fn = function(childKey) {
2036
+ const cfg = this.childConfigs[childKey];
2037
+ if (!cfg) {
2038
+ throw new Error(
2039
+ `BaseFlowProducer: no child queue declared under key "${childKey}". Declared keys: [${Object.keys(this.childConfigs).join(", ")}]`
2040
+ );
2041
+ }
2042
+ return cfg;
2043
+ };
2044
+ module2.exports = { BaseFlowProducer: BaseFlowProducer2 };
2045
+ }
2046
+ });
2047
+
1915
2048
  // src/bullmq/BaseWorker.js
1916
2049
  var require_BaseWorker = __commonJS({
1917
2050
  "src/bullmq/BaseWorker.js"(exports2, module2) {
@@ -2102,6 +2235,7 @@ __export(node_exports, {
2102
2235
  AnnosElasticSyncProducer: () => import_AnnosElasticSyncProducer.AnnosElasticSyncProducer,
2103
2236
  AnnotationSchema: () => Annotations_default,
2104
2237
  BASE_BULLMQ_CONFIG: () => BASE_BULLMQ_CONFIG,
2238
+ BaseFlowProducer: () => import_BaseFlowProducer.BaseFlowProducer,
2105
2239
  BaseProducer: () => import_BaseProducer.BaseProducer,
2106
2240
  BaseWorker: () => import_BaseWorker.BaseWorker,
2107
2241
  BlockRegistry: () => BlockRegistry,
@@ -4686,9 +4820,9 @@ var RedisCacheConnector = class _RedisCacheConnector {
4686
4820
  * @param {string} [params.tenant] - Tenant (either a single tenant or an array of tenants for whom the config cache should be refreshed)
4687
4821
  * @static
4688
4822
  */
4689
- static async loadTplsAndPlatformConfigsToCache({ tenant }) {
4823
+ static async loadTplsAndPlatformConfigsToCache({ tenant, env }) {
4690
4824
  try {
4691
- const environment = this.getEnv();
4825
+ const environment = env || this.getEnv();
4692
4826
  const client = this.getClient(environment);
4693
4827
  if (!tenant) throw new Error("No tenant/s defined to recache");
4694
4828
  console.log(`Loading configs and templates into cache...`);
@@ -4720,7 +4854,8 @@ var RedisCacheConnector = class _RedisCacheConnector {
4720
4854
  tenant: tenant2,
4721
4855
  modelName,
4722
4856
  type,
4723
- val: doc
4857
+ val: doc,
4858
+ env: environment
4724
4859
  });
4725
4860
  })
4726
4861
  );
@@ -4766,6 +4901,7 @@ init_models();
4766
4901
  var import_WorkerManager = __toESM(require_WorkerManager());
4767
4902
  var import_ProducerManager = __toESM(require_ProducerManager());
4768
4903
  var import_BaseProducer = __toESM(require_BaseProducer());
4904
+ var import_BaseFlowProducer = __toESM(require_BaseFlowProducer());
4769
4905
  var import_BaseWorker = __toESM(require_BaseWorker());
4770
4906
  var import_ChunksElasticSyncProducer = __toESM(require_ChunksElasticSyncProducer());
4771
4907
  var import_AnnosElasticSyncProducer = __toESM(require_AnnosElasticSyncProducer());
@@ -4776,6 +4912,7 @@ var import_GET_GLOBAL_BULLMQ_CONFIG = __toESM(require_GET_GLOBAL_BULLMQ_CONFIG()
4776
4912
  AnnosElasticSyncProducer,
4777
4913
  AnnotationSchema,
4778
4914
  BASE_BULLMQ_CONFIG,
4915
+ BaseFlowProducer,
4779
4916
  BaseProducer,
4780
4917
  BaseWorker,
4781
4918
  BlockRegistry,
package/dist/node.mjs CHANGED
@@ -4,6 +4,9 @@ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
4
  var __getOwnPropNames = Object.getOwnPropertyNames;
5
5
  var __getProtoOf = Object.getPrototypeOf;
6
6
  var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ var __typeError = (msg) => {
8
+ throw TypeError(msg);
9
+ };
7
10
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
8
11
  var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
9
12
  get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
@@ -39,6 +42,9 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
39
42
  ));
40
43
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
41
44
  var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
45
+ var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg);
46
+ var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
47
+ var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "access private method"), method);
42
48
 
43
49
  // src/bullmq/GLOBAL_BULLMQ_CONFIG.js
44
50
  var GLOBAL_BULLMQ_CONFIG_exports = {};
@@ -1917,6 +1923,133 @@ var require_BaseProducer = __commonJS({
1917
1923
  }
1918
1924
  });
1919
1925
 
1926
+ // src/bullmq/BaseFlowProducer.js
1927
+ var require_BaseFlowProducer = __commonJS({
1928
+ "src/bullmq/BaseFlowProducer.js"(exports, module) {
1929
+ "use strict";
1930
+ var { FlowProducer, Queue } = __require("bullmq");
1931
+ var _BaseFlowProducer_instances, mergeOpts_fn, childConfig_fn;
1932
+ var BaseFlowProducer2 = class {
1933
+ constructor({ parentConfig, childConfigs = {} }) {
1934
+ __privateAdd(this, _BaseFlowProducer_instances);
1935
+ if (!parentConfig) {
1936
+ throw new Error("BaseFlowProducer requires a parentConfig");
1937
+ }
1938
+ this.parentConfig = parentConfig;
1939
+ this.childConfigs = childConfigs;
1940
+ this.flow = new FlowProducer({
1941
+ connection: parentConfig.queueConfig.connection
1942
+ });
1943
+ }
1944
+ /**
1945
+ * Build & enqueue a flow declaratively.
1946
+ *
1947
+ * @param {Object} params
1948
+ * @param {string} [params.name] Parent job name.
1949
+ * @param {Object} params.parentData Parent job data.
1950
+ * @param {Object} [params.parentOpts] Per-node opts for the parent, layered
1951
+ * over the parent queue's defaults.
1952
+ * @param {Array} params.children One entry per child node:
1953
+ * @param {string} children[].childKey Key into childConfigs (which queue).
1954
+ * @param {string} [children[].name] Child job name.
1955
+ * @param {Object} children[].data Child job data.
1956
+ * @param {Object} [children[].opts] Job-specific opts (e.g.
1957
+ * failParentOnFailure); layered over
1958
+ * that child queue's defaults.
1959
+ * @returns {Promise<{ parentJobId, childJobIds }>}
1960
+ */
1961
+ async addFlow({ name, parentData, parentOpts = {}, children = [] }) {
1962
+ const flowJob = await this.flow.add({
1963
+ name,
1964
+ queueName: this.parentConfig.id,
1965
+ data: parentData,
1966
+ opts: __privateMethod(this, _BaseFlowProducer_instances, mergeOpts_fn).call(this, this.parentConfig, parentOpts),
1967
+ children: children.map((child) => {
1968
+ const childCfg = __privateMethod(this, _BaseFlowProducer_instances, childConfig_fn).call(this, child.childKey);
1969
+ return {
1970
+ name: child.name,
1971
+ queueName: childCfg.id,
1972
+ data: child.data,
1973
+ opts: __privateMethod(this, _BaseFlowProducer_instances, mergeOpts_fn).call(this, childCfg, child.opts)
1974
+ };
1975
+ })
1976
+ });
1977
+ const parentJobId = flowJob?.job?.id;
1978
+ const childJobIds = (flowJob?.children || []).map((c) => c?.job?.id).filter(Boolean);
1979
+ return { parentJobId, childJobIds };
1980
+ }
1981
+ /**
1982
+ * Find the FIRST parent job in the given states whose data matches the
1983
+ * predicate — e.g. an in-flight lock check ("is a run already pending for
1984
+ * this tenant?"). Opens a short-lived Queue on the parent queue and closes
1985
+ * it before returning, so callers don't have to reach into config internals
1986
+ * to construct one themselves.
1987
+ *
1988
+ * Returns the first match or null. BullMQ can't filter by job.data
1989
+ * server-side, so this still fetches the in-flight set and scans in JS; the
1990
+ * contract is intentionally first-match (not a list) because that's the only
1991
+ * thing the lock-check use case needs.
1992
+ *
1993
+ * @param {Object} params
1994
+ * @param {string[]} params.states
1995
+ * Job states to scan, e.g. ["waiting", "active", "delayed"].
1996
+ * @param {(data: any, job: any) => boolean} params.matchData
1997
+ * Required function; receives job.data (and the job). Without it there's
1998
+ * no meaningful "match", so this throws — returning an arbitrary in-flight
1999
+ * job would be a silent caller bug.
2000
+ * @returns {Promise<Object|null>} The first matching parent job, or null.
2001
+ */
2002
+ async findParentJob({ states, matchData }) {
2003
+ if (typeof matchData !== "function") {
2004
+ throw new Error("BaseFlowProducer.findParentJob requires a matchData function");
2005
+ }
2006
+ const parentQueue = new Queue(
2007
+ this.parentConfig.id,
2008
+ this.parentConfig.queueConfig
2009
+ );
2010
+ try {
2011
+ const jobs = await parentQueue.getJobs(states, 0, -1);
2012
+ return jobs.find((job) => matchData(job?.data, job)) || null;
2013
+ } finally {
2014
+ await parentQueue.close();
2015
+ }
2016
+ }
2017
+ async stop() {
2018
+ if (this.flow) {
2019
+ try {
2020
+ await this.flow.close();
2021
+ } catch (err) {
2022
+ console.warn(`[${this.constructor.name}] flow close failed: ${err.message}`);
2023
+ }
2024
+ }
2025
+ }
2026
+ };
2027
+ _BaseFlowProducer_instances = new WeakSet();
2028
+ /**
2029
+ * Layer a queue config's defaultJobOptions under per-node opts — identical
2030
+ * to how BullMQ merges defaultJobOptions under per-`add` opts for a Queue.
2031
+ * Config is the base; anything the node explicitly sets wins.
2032
+ */
2033
+ mergeOpts_fn = function(queueConfig, nodeOpts = {}) {
2034
+ const defaults = queueConfig?.queueConfig?.defaultJobOptions || {};
2035
+ return { ...defaults, ...nodeOpts };
2036
+ };
2037
+ /**
2038
+ * Resolve the GLOBAL_BULLMQ_CONFIG entry for a declared child key.
2039
+ */
2040
+ childConfig_fn = function(childKey) {
2041
+ const cfg = this.childConfigs[childKey];
2042
+ if (!cfg) {
2043
+ throw new Error(
2044
+ `BaseFlowProducer: no child queue declared under key "${childKey}". Declared keys: [${Object.keys(this.childConfigs).join(", ")}]`
2045
+ );
2046
+ }
2047
+ return cfg;
2048
+ };
2049
+ module.exports = { BaseFlowProducer: BaseFlowProducer2 };
2050
+ }
2051
+ });
2052
+
1920
2053
  // src/bullmq/BaseWorker.js
1921
2054
  var require_BaseWorker = __commonJS({
1922
2055
  "src/bullmq/BaseWorker.js"(exports, module) {
@@ -4615,9 +4748,9 @@ var RedisCacheConnector = class _RedisCacheConnector {
4615
4748
  * @param {string} [params.tenant] - Tenant (either a single tenant or an array of tenants for whom the config cache should be refreshed)
4616
4749
  * @static
4617
4750
  */
4618
- static async loadTplsAndPlatformConfigsToCache({ tenant }) {
4751
+ static async loadTplsAndPlatformConfigsToCache({ tenant, env }) {
4619
4752
  try {
4620
- const environment = this.getEnv();
4753
+ const environment = env || this.getEnv();
4621
4754
  const client = this.getClient(environment);
4622
4755
  if (!tenant) throw new Error("No tenant/s defined to recache");
4623
4756
  console.log(`Loading configs and templates into cache...`);
@@ -4649,7 +4782,8 @@ var RedisCacheConnector = class _RedisCacheConnector {
4649
4782
  tenant: tenant2,
4650
4783
  modelName,
4651
4784
  type,
4652
- val: doc
4785
+ val: doc,
4786
+ env: environment
4653
4787
  });
4654
4788
  })
4655
4789
  );
@@ -4695,11 +4829,13 @@ init_models();
4695
4829
  var import_WorkerManager = __toESM(require_WorkerManager());
4696
4830
  var import_ProducerManager = __toESM(require_ProducerManager());
4697
4831
  var import_BaseProducer = __toESM(require_BaseProducer());
4832
+ var import_BaseFlowProducer = __toESM(require_BaseFlowProducer());
4698
4833
  var import_BaseWorker = __toESM(require_BaseWorker());
4699
4834
  var import_ChunksElasticSyncProducer = __toESM(require_ChunksElasticSyncProducer());
4700
4835
  var import_AnnosElasticSyncProducer = __toESM(require_AnnosElasticSyncProducer());
4701
4836
  var import_GET_GLOBAL_BULLMQ_CONFIG = __toESM(require_GET_GLOBAL_BULLMQ_CONFIG());
4702
4837
  var export_AnnosElasticSyncProducer = import_AnnosElasticSyncProducer.AnnosElasticSyncProducer;
4838
+ var export_BaseFlowProducer = import_BaseFlowProducer.BaseFlowProducer;
4703
4839
  var export_BaseProducer = import_BaseProducer.BaseProducer;
4704
4840
  var export_BaseWorker = import_BaseWorker.BaseWorker;
4705
4841
  var export_ChunksElasticSyncProducer = import_ChunksElasticSyncProducer.ChunksElasticSyncProducer;
@@ -4720,6 +4856,7 @@ export {
4720
4856
  export_AnnosElasticSyncProducer as AnnosElasticSyncProducer,
4721
4857
  Annotations_default as AnnotationSchema,
4722
4858
  BASE_BULLMQ_CONFIG,
4859
+ export_BaseFlowProducer as BaseFlowProducer,
4723
4860
  export_BaseProducer as BaseProducer,
4724
4861
  export_BaseWorker as BaseWorker,
4725
4862
  BlockRegistry,
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "publishConfig": {
4
4
  "access": "public"
5
5
  },
6
- "version": "1.39.2",
6
+ "version": "1.40.0",
7
7
  "description": "Utility functions for both browser and Node.js",
8
8
  "main": "dist/index.js",
9
9
  "module": "dist/index.mjs",