@rotorsoft/act 0.6.28 → 0.6.29
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/.tsbuildinfo +1 -1
- package/dist/@types/act-builder.d.ts +286 -41
- package/dist/@types/act-builder.d.ts.map +1 -1
- package/dist/@types/act.d.ts +354 -52
- package/dist/@types/act.d.ts.map +1 -1
- package/dist/@types/adapters/InMemoryStore.d.ts +59 -8
- package/dist/@types/adapters/InMemoryStore.d.ts.map +1 -1
- package/dist/@types/config.d.ts +54 -6
- package/dist/@types/config.d.ts.map +1 -1
- package/dist/@types/ports.d.ts +149 -10
- package/dist/@types/ports.d.ts.map +1 -1
- package/dist/@types/state-builder.d.ts +318 -43
- package/dist/@types/state-builder.d.ts.map +1 -1
- package/dist/@types/types/action.d.ts +122 -10
- package/dist/@types/types/action.d.ts.map +1 -1
- package/dist/@types/types/errors.d.ts +211 -22
- package/dist/@types/types/errors.d.ts.map +1 -1
- package/dist/@types/types/ports.d.ts +204 -28
- package/dist/@types/types/ports.d.ts.map +1 -1
- package/dist/@types/types/reaction.d.ts +107 -18
- package/dist/@types/types/reaction.d.ts.map +1 -1
- package/dist/@types/utils.d.ts +378 -27
- package/dist/@types/utils.d.ts.map +1 -1
- package/dist/index.cjs +352 -50
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +352 -50
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -779,18 +779,87 @@ var Act = class {
|
|
|
779
779
|
return this;
|
|
780
780
|
}
|
|
781
781
|
/**
|
|
782
|
-
* Executes an action
|
|
782
|
+
* Executes an action on a state instance, committing resulting events.
|
|
783
783
|
*
|
|
784
|
-
*
|
|
785
|
-
*
|
|
786
|
-
*
|
|
787
|
-
*
|
|
788
|
-
*
|
|
789
|
-
*
|
|
790
|
-
*
|
|
784
|
+
* This is the primary method for modifying state. It:
|
|
785
|
+
* 1. Validates the action payload against the schema
|
|
786
|
+
* 2. Loads the current state snapshot
|
|
787
|
+
* 3. Checks invariants (business rules)
|
|
788
|
+
* 4. Executes the action handler to generate events
|
|
789
|
+
* 5. Applies events to create new state
|
|
790
|
+
* 6. Commits events to the store with optimistic concurrency control
|
|
791
791
|
*
|
|
792
|
-
* @
|
|
793
|
-
*
|
|
792
|
+
* @template K - Action name from registered actions
|
|
793
|
+
* @param action - The name of the action to execute
|
|
794
|
+
* @param target - Target specification with stream ID and actor context
|
|
795
|
+
* @param payload - Action payload matching the action's schema
|
|
796
|
+
* @param reactingTo - Optional event that triggered this action (for correlation)
|
|
797
|
+
* @param skipValidation - Skip schema validation (use carefully, for performance)
|
|
798
|
+
* @returns Array of snapshots for all affected states (usually one)
|
|
799
|
+
*
|
|
800
|
+
* @throws {ValidationError} If payload doesn't match action schema
|
|
801
|
+
* @throws {InvariantError} If business rules are violated
|
|
802
|
+
* @throws {ConcurrencyError} If another process modified the stream
|
|
803
|
+
*
|
|
804
|
+
* @example Basic action execution
|
|
805
|
+
* ```typescript
|
|
806
|
+
* const snapshots = await app.do(
|
|
807
|
+
* "increment",
|
|
808
|
+
* {
|
|
809
|
+
* stream: "counter-1",
|
|
810
|
+
* actor: { id: "user1", name: "Alice" }
|
|
811
|
+
* },
|
|
812
|
+
* { by: 5 }
|
|
813
|
+
* );
|
|
814
|
+
*
|
|
815
|
+
* console.log(snapshots[0].state.count); // Current count after increment
|
|
816
|
+
* ```
|
|
817
|
+
*
|
|
818
|
+
* @example With error handling
|
|
819
|
+
* ```typescript
|
|
820
|
+
* try {
|
|
821
|
+
* await app.do(
|
|
822
|
+
* "withdraw",
|
|
823
|
+
* { stream: "account-123", actor: { id: "user1", name: "Alice" } },
|
|
824
|
+
* { amount: 1000 }
|
|
825
|
+
* );
|
|
826
|
+
* } catch (error) {
|
|
827
|
+
* if (error instanceof InvariantError) {
|
|
828
|
+
* console.error("Business rule violated:", error.description);
|
|
829
|
+
* } else if (error instanceof ConcurrencyError) {
|
|
830
|
+
* console.error("Concurrent modification detected, retry...");
|
|
831
|
+
* } else if (error instanceof ValidationError) {
|
|
832
|
+
* console.error("Invalid payload:", error.details);
|
|
833
|
+
* }
|
|
834
|
+
* }
|
|
835
|
+
* ```
|
|
836
|
+
*
|
|
837
|
+
* @example Reaction triggering another action
|
|
838
|
+
* ```typescript
|
|
839
|
+
* const app = act()
|
|
840
|
+
* .with(Order)
|
|
841
|
+
* .with(Inventory)
|
|
842
|
+
* .on("OrderPlaced")
|
|
843
|
+
* .do(async (event, context) => {
|
|
844
|
+
* // This action is triggered by an event
|
|
845
|
+
* const result = await context.app.do(
|
|
846
|
+
* "reduceStock",
|
|
847
|
+
* {
|
|
848
|
+
* stream: "inventory-1",
|
|
849
|
+
* actor: event.meta.causation.action.actor
|
|
850
|
+
* },
|
|
851
|
+
* { amount: event.data.items.length },
|
|
852
|
+
* event // Pass event for correlation tracking
|
|
853
|
+
* );
|
|
854
|
+
* return result;
|
|
855
|
+
* })
|
|
856
|
+
* .to("inventory-1")
|
|
857
|
+
* .build();
|
|
858
|
+
* ```
|
|
859
|
+
*
|
|
860
|
+
* @see {@link Target} for target structure
|
|
861
|
+
* @see {@link Snapshot} for return value structure
|
|
862
|
+
* @see {@link ValidationError}, {@link InvariantError}, {@link ConcurrencyError}
|
|
794
863
|
*/
|
|
795
864
|
async do(action2, target, payload, reactingTo, skipValidation = false) {
|
|
796
865
|
const snapshots = await action(
|
|
@@ -806,31 +875,97 @@ var Act = class {
|
|
|
806
875
|
return snapshots;
|
|
807
876
|
}
|
|
808
877
|
/**
|
|
809
|
-
* Loads the current state snapshot for a
|
|
878
|
+
* Loads the current state snapshot for a specific stream.
|
|
810
879
|
*
|
|
811
|
-
*
|
|
812
|
-
*
|
|
813
|
-
* @template AX The type of actions
|
|
814
|
-
* @param state The state machine definition
|
|
815
|
-
* @param stream The stream (instance) to load
|
|
816
|
-
* @param callback (Optional) Callback to receive the loaded snapshot
|
|
817
|
-
* @returns The snapshot of the loaded state
|
|
880
|
+
* Reconstructs the current state by replaying events from the event store.
|
|
881
|
+
* Uses snapshots when available to optimize loading performance.
|
|
818
882
|
*
|
|
819
|
-
* @
|
|
820
|
-
*
|
|
883
|
+
* @template SX - State schema type
|
|
884
|
+
* @template EX - Event schemas type
|
|
885
|
+
* @template AX - Action schemas type
|
|
886
|
+
* @param state - The state definition to load
|
|
887
|
+
* @param stream - The stream ID (state instance identifier)
|
|
888
|
+
* @param callback - Optional callback invoked with the loaded snapshot
|
|
889
|
+
* @returns The current state snapshot for the stream
|
|
890
|
+
*
|
|
891
|
+
* @example Load current state
|
|
892
|
+
* ```typescript
|
|
893
|
+
* const snapshot = await app.load(Counter, "counter-1");
|
|
894
|
+
* console.log(snapshot.state.count); // Current count
|
|
895
|
+
* console.log(snapshot.version); // Number of events applied
|
|
896
|
+
* console.log(snapshot.patches); // Events since last snapshot
|
|
897
|
+
* ```
|
|
898
|
+
*
|
|
899
|
+
* @example With callback
|
|
900
|
+
* ```typescript
|
|
901
|
+
* const snapshot = await app.load(User, "user-123", (snap) => {
|
|
902
|
+
* console.log("Loaded user:", snap.state.name);
|
|
903
|
+
* });
|
|
904
|
+
* ```
|
|
905
|
+
*
|
|
906
|
+
* @example Load multiple states
|
|
907
|
+
* ```typescript
|
|
908
|
+
* const [user, account] = await Promise.all([
|
|
909
|
+
* app.load(User, "user-123"),
|
|
910
|
+
* app.load(BankAccount, "account-456")
|
|
911
|
+
* ]);
|
|
912
|
+
* ```
|
|
913
|
+
*
|
|
914
|
+
* @see {@link Snapshot} for snapshot structure
|
|
821
915
|
*/
|
|
822
916
|
async load(state2, stream, callback) {
|
|
823
917
|
return await load(state2, stream, callback);
|
|
824
918
|
}
|
|
825
919
|
/**
|
|
826
|
-
*
|
|
920
|
+
* Queries the event store for events matching a filter.
|
|
827
921
|
*
|
|
828
|
-
*
|
|
829
|
-
*
|
|
830
|
-
*
|
|
922
|
+
* Use this for analyzing event streams, generating reports, or debugging.
|
|
923
|
+
* The callback is invoked for each matching event, and the method returns
|
|
924
|
+
* summary information (first event, last event, total count).
|
|
831
925
|
*
|
|
832
|
-
* @
|
|
833
|
-
*
|
|
926
|
+
* For small result sets, consider using {@link query_array} instead.
|
|
927
|
+
*
|
|
928
|
+
* @param query - The query filter
|
|
929
|
+
* @param query.stream - Filter by stream ID
|
|
930
|
+
* @param query.name - Filter by event name
|
|
931
|
+
* @param query.after - Filter events after this event ID
|
|
932
|
+
* @param query.before - Filter events before this event ID
|
|
933
|
+
* @param query.created_after - Filter events after this timestamp
|
|
934
|
+
* @param query.created_before - Filter events before this timestamp
|
|
935
|
+
* @param query.limit - Maximum number of events to return
|
|
936
|
+
* @param callback - Optional callback invoked for each matching event
|
|
937
|
+
* @returns Object with first event, last event, and total count
|
|
938
|
+
*
|
|
939
|
+
* @example Query all events for a stream
|
|
940
|
+
* ```typescript
|
|
941
|
+
* const { first, last, count } = await app.query(
|
|
942
|
+
* { stream: "counter-1" },
|
|
943
|
+
* (event) => console.log(event.name, event.data)
|
|
944
|
+
* );
|
|
945
|
+
* console.log(`Found ${count} events from ${first?.id} to ${last?.id}`);
|
|
946
|
+
* ```
|
|
947
|
+
*
|
|
948
|
+
* @example Query specific event types
|
|
949
|
+
* ```typescript
|
|
950
|
+
* const { count } = await app.query(
|
|
951
|
+
* { name: "UserCreated", limit: 100 },
|
|
952
|
+
* (event) => {
|
|
953
|
+
* console.log("User created:", event.data.email);
|
|
954
|
+
* }
|
|
955
|
+
* );
|
|
956
|
+
* ```
|
|
957
|
+
*
|
|
958
|
+
* @example Query events in time range
|
|
959
|
+
* ```typescript
|
|
960
|
+
* const yesterday = new Date(Date.now() - 24 * 60 * 60 * 1000);
|
|
961
|
+
* const { count } = await app.query({
|
|
962
|
+
* created_after: yesterday,
|
|
963
|
+
* stream: "user-123"
|
|
964
|
+
* });
|
|
965
|
+
* console.log(`User had ${count} events in last 24 hours`);
|
|
966
|
+
* ```
|
|
967
|
+
*
|
|
968
|
+
* @see {@link query_array} for loading events into memory
|
|
834
969
|
*/
|
|
835
970
|
async query(query, callback) {
|
|
836
971
|
let first = void 0, last = void 0;
|
|
@@ -842,14 +977,30 @@ var Act = class {
|
|
|
842
977
|
return { first, last, count };
|
|
843
978
|
}
|
|
844
979
|
/**
|
|
845
|
-
*
|
|
846
|
-
* Use this version with caution, as it return events in memory.
|
|
980
|
+
* Queries the event store and returns all matching events in memory.
|
|
847
981
|
*
|
|
848
|
-
*
|
|
849
|
-
* @
|
|
982
|
+
* **Use with caution** - this loads all results into memory. For large result sets,
|
|
983
|
+
* use {@link query} with a callback instead to process events incrementally.
|
|
850
984
|
*
|
|
851
|
-
* @
|
|
852
|
-
*
|
|
985
|
+
* @param query - The query filter (same as {@link query})
|
|
986
|
+
* @returns Array of all matching events
|
|
987
|
+
*
|
|
988
|
+
* @example Load all events for a stream
|
|
989
|
+
* ```typescript
|
|
990
|
+
* const events = await app.query_array({ stream: "counter-1" });
|
|
991
|
+
* console.log(`Loaded ${events.length} events`);
|
|
992
|
+
* events.forEach(event => console.log(event.name, event.data));
|
|
993
|
+
* ```
|
|
994
|
+
*
|
|
995
|
+
* @example Get recent events
|
|
996
|
+
* ```typescript
|
|
997
|
+
* const recent = await app.query_array({
|
|
998
|
+
* stream: "user-123",
|
|
999
|
+
* limit: 10
|
|
1000
|
+
* });
|
|
1001
|
+
* ```
|
|
1002
|
+
*
|
|
1003
|
+
* @see {@link query} for large result sets
|
|
853
1004
|
*/
|
|
854
1005
|
async query_array(query) {
|
|
855
1006
|
const events = [];
|
|
@@ -895,14 +1046,68 @@ var Act = class {
|
|
|
895
1046
|
return { lease, handled, at };
|
|
896
1047
|
}
|
|
897
1048
|
/**
|
|
898
|
-
*
|
|
1049
|
+
* Processes pending reactions by draining uncommitted events from the event store.
|
|
899
1050
|
*
|
|
900
|
-
*
|
|
1051
|
+
* The drain process:
|
|
1052
|
+
* 1. Polls the store for streams with uncommitted events
|
|
1053
|
+
* 2. Leases streams to prevent concurrent processing
|
|
1054
|
+
* 3. Fetches events for each leased stream
|
|
1055
|
+
* 4. Executes matching reaction handlers
|
|
1056
|
+
* 5. Acknowledges successful reactions or blocks failing ones
|
|
901
1057
|
*
|
|
902
|
-
*
|
|
1058
|
+
* Drain uses a dual-frontier strategy to balance processing of new streams (lagging)
|
|
1059
|
+
* vs active streams (leading). The ratio adapts based on event pressure.
|
|
903
1060
|
*
|
|
904
|
-
*
|
|
1061
|
+
* Call this method periodically in a background loop, or after committing events.
|
|
1062
|
+
*
|
|
1063
|
+
* @param options - Drain configuration options
|
|
1064
|
+
* @param options.streamLimit - Maximum number of streams to process per cycle (default: 10)
|
|
1065
|
+
* @param options.eventLimit - Maximum events to fetch per stream (default: 10)
|
|
1066
|
+
* @param options.leaseMillis - Lease duration in milliseconds (default: 10000)
|
|
1067
|
+
* @returns Drain statistics with fetched, leased, acked, and blocked counts
|
|
1068
|
+
*
|
|
1069
|
+
* @example Basic drain loop
|
|
1070
|
+
* ```typescript
|
|
1071
|
+
* // Process reactions after each action
|
|
1072
|
+
* await app.do("createUser", target, payload);
|
|
905
1073
|
* await app.drain();
|
|
1074
|
+
* ```
|
|
1075
|
+
*
|
|
1076
|
+
* @example Background drain worker
|
|
1077
|
+
* ```typescript
|
|
1078
|
+
* setInterval(async () => {
|
|
1079
|
+
* try {
|
|
1080
|
+
* const result = await app.drain({
|
|
1081
|
+
* streamLimit: 20,
|
|
1082
|
+
* eventLimit: 50
|
|
1083
|
+
* });
|
|
1084
|
+
* if (result.acked.length) {
|
|
1085
|
+
* console.log(`Processed ${result.acked.length} streams`);
|
|
1086
|
+
* }
|
|
1087
|
+
* } catch (error) {
|
|
1088
|
+
* console.error("Drain error:", error);
|
|
1089
|
+
* }
|
|
1090
|
+
* }, 5000); // Every 5 seconds
|
|
1091
|
+
* ```
|
|
1092
|
+
*
|
|
1093
|
+
* @example With lifecycle listeners
|
|
1094
|
+
* ```typescript
|
|
1095
|
+
* app.on("acked", (leases) => {
|
|
1096
|
+
* console.log(`Acknowledged ${leases.length} streams`);
|
|
1097
|
+
* });
|
|
1098
|
+
*
|
|
1099
|
+
* app.on("blocked", (blocked) => {
|
|
1100
|
+
* console.error(`Blocked ${blocked.length} streams due to errors`);
|
|
1101
|
+
* blocked.forEach(({ stream, error }) => {
|
|
1102
|
+
* console.error(`Stream ${stream}: ${error}`);
|
|
1103
|
+
* });
|
|
1104
|
+
* });
|
|
1105
|
+
*
|
|
1106
|
+
* await app.drain();
|
|
1107
|
+
* ```
|
|
1108
|
+
*
|
|
1109
|
+
* @see {@link correlate} for dynamic stream discovery
|
|
1110
|
+
* @see {@link start_correlations} for automatic correlation
|
|
906
1111
|
*/
|
|
907
1112
|
async drain({
|
|
908
1113
|
streamLimit = 10,
|
|
@@ -999,9 +1204,49 @@ var Act = class {
|
|
|
999
1204
|
return { fetched: [], leased: [], acked: [], blocked: [] };
|
|
1000
1205
|
}
|
|
1001
1206
|
/**
|
|
1002
|
-
*
|
|
1003
|
-
*
|
|
1004
|
-
*
|
|
1207
|
+
* Discovers and registers new streams dynamically based on reaction resolvers.
|
|
1208
|
+
*
|
|
1209
|
+
* Correlation enables "dynamic reactions" where target streams are determined at runtime
|
|
1210
|
+
* based on event content. For example, you might create a stats stream for each user
|
|
1211
|
+
* when they perform certain actions.
|
|
1212
|
+
*
|
|
1213
|
+
* This method scans events matching the query and identifies new target streams based
|
|
1214
|
+
* on reaction resolvers. It then registers these streams so they'll be picked up by
|
|
1215
|
+
* the next drain cycle.
|
|
1216
|
+
*
|
|
1217
|
+
* @param query - Query filter to scan for new correlations
|
|
1218
|
+
* @param query.after - Start scanning after this event ID (default: -1)
|
|
1219
|
+
* @param query.limit - Maximum events to scan (default: 10)
|
|
1220
|
+
* @returns Object with newly leased streams and last scanned event ID
|
|
1221
|
+
*
|
|
1222
|
+
* @example Manual correlation
|
|
1223
|
+
* ```typescript
|
|
1224
|
+
* // Scan for new streams
|
|
1225
|
+
* const { leased, last_id } = await app.correlate({ after: 0, limit: 100 });
|
|
1226
|
+
* console.log(`Found ${leased.length} new streams`);
|
|
1227
|
+
*
|
|
1228
|
+
* // Save last_id for next scan
|
|
1229
|
+
* await saveCheckpoint(last_id);
|
|
1230
|
+
* ```
|
|
1231
|
+
*
|
|
1232
|
+
* @example Dynamic stream creation
|
|
1233
|
+
* ```typescript
|
|
1234
|
+
* const app = act()
|
|
1235
|
+
* .with(User)
|
|
1236
|
+
* .with(UserStats)
|
|
1237
|
+
* .on("UserLoggedIn")
|
|
1238
|
+
* .do(async (event) => ["incrementLoginCount", {}])
|
|
1239
|
+
* .to((event) => ({
|
|
1240
|
+
* target: `stats-${event.stream}` // Dynamic target per user
|
|
1241
|
+
* }))
|
|
1242
|
+
* .build();
|
|
1243
|
+
*
|
|
1244
|
+
* // Discover stats streams as users log in
|
|
1245
|
+
* await app.correlate();
|
|
1246
|
+
* ```
|
|
1247
|
+
*
|
|
1248
|
+
* @see {@link start_correlations} for automatic periodic correlation
|
|
1249
|
+
* @see {@link stop_correlations} to stop automatic correlation
|
|
1005
1250
|
*/
|
|
1006
1251
|
async correlate(query = { after: -1, limit: 10 }) {
|
|
1007
1252
|
const correlated = /* @__PURE__ */ new Map();
|
|
@@ -1034,19 +1279,59 @@ var Act = class {
|
|
|
1034
1279
|
return { leased: [], last_id };
|
|
1035
1280
|
}
|
|
1036
1281
|
/**
|
|
1037
|
-
* Starts correlation worker
|
|
1282
|
+
* Starts automatic periodic correlation worker for discovering new streams.
|
|
1283
|
+
*
|
|
1284
|
+
* The correlation worker runs in the background, scanning for new events and identifying
|
|
1285
|
+
* new target streams based on reaction resolvers. It maintains a sliding window that
|
|
1286
|
+
* advances with each scan, ensuring all events are eventually correlated.
|
|
1038
1287
|
*
|
|
1039
|
-
*
|
|
1040
|
-
* -
|
|
1041
|
-
* - Once registered, these streams are picked up by the main `drain` loop.
|
|
1042
|
-
* - Users should have full control over their correlation strategy.
|
|
1043
|
-
* - The starting point keeps increasing with each new batch of events.
|
|
1044
|
-
* - Users are responsible for storing the last seen event ID.
|
|
1288
|
+
* This is useful for dynamic stream creation patterns where you don't know all streams
|
|
1289
|
+
* upfront - they're discovered as events arrive.
|
|
1045
1290
|
*
|
|
1046
|
-
*
|
|
1047
|
-
*
|
|
1048
|
-
* @param
|
|
1049
|
-
* @
|
|
1291
|
+
* **Note:** Only one correlation worker can run at a time per Act instance.
|
|
1292
|
+
*
|
|
1293
|
+
* @param query - Query filter for correlation scans
|
|
1294
|
+
* @param query.after - Initial starting point (default: -1, start from beginning)
|
|
1295
|
+
* @param query.limit - Events to scan per cycle (default: 100)
|
|
1296
|
+
* @param frequency - Correlation frequency in milliseconds (default: 10000)
|
|
1297
|
+
* @param callback - Optional callback invoked with newly discovered streams
|
|
1298
|
+
* @returns `true` if worker started, `false` if already running
|
|
1299
|
+
*
|
|
1300
|
+
* @example Start automatic correlation
|
|
1301
|
+
* ```typescript
|
|
1302
|
+
* // Start correlation worker scanning every 5 seconds
|
|
1303
|
+
* app.start_correlations(
|
|
1304
|
+
* { after: 0, limit: 100 },
|
|
1305
|
+
* 5000,
|
|
1306
|
+
* (leased) => {
|
|
1307
|
+
* console.log(`Discovered ${leased.length} new streams`);
|
|
1308
|
+
* }
|
|
1309
|
+
* );
|
|
1310
|
+
*
|
|
1311
|
+
* // Later, stop it
|
|
1312
|
+
* app.stop_correlations();
|
|
1313
|
+
* ```
|
|
1314
|
+
*
|
|
1315
|
+
* @example With checkpoint persistence
|
|
1316
|
+
* ```typescript
|
|
1317
|
+
* // Load last checkpoint
|
|
1318
|
+
* const lastId = await loadCheckpoint();
|
|
1319
|
+
*
|
|
1320
|
+
* app.start_correlations(
|
|
1321
|
+
* { after: lastId, limit: 100 },
|
|
1322
|
+
* 10000,
|
|
1323
|
+
* async (leased) => {
|
|
1324
|
+
* // Save checkpoint for next restart
|
|
1325
|
+
* if (leased.length) {
|
|
1326
|
+
* const maxId = Math.max(...leased.map(l => l.at));
|
|
1327
|
+
* await saveCheckpoint(maxId);
|
|
1328
|
+
* }
|
|
1329
|
+
* }
|
|
1330
|
+
* );
|
|
1331
|
+
* ```
|
|
1332
|
+
*
|
|
1333
|
+
* @see {@link correlate} for manual one-time correlation
|
|
1334
|
+
* @see {@link stop_correlations} to stop the worker
|
|
1050
1335
|
*/
|
|
1051
1336
|
start_correlations(query = {}, frequency = 1e4, callback) {
|
|
1052
1337
|
if (this._correlation_interval) return false;
|
|
@@ -1061,6 +1346,23 @@ var Act = class {
|
|
|
1061
1346
|
);
|
|
1062
1347
|
return true;
|
|
1063
1348
|
}
|
|
1349
|
+
/**
|
|
1350
|
+
* Stops the automatic correlation worker.
|
|
1351
|
+
*
|
|
1352
|
+
* Call this to stop the background correlation worker started by {@link start_correlations}.
|
|
1353
|
+
* This is automatically called when the Act instance is disposed.
|
|
1354
|
+
*
|
|
1355
|
+
* @example
|
|
1356
|
+
* ```typescript
|
|
1357
|
+
* // Start correlation
|
|
1358
|
+
* app.start_correlations();
|
|
1359
|
+
*
|
|
1360
|
+
* // Later, stop it
|
|
1361
|
+
* app.stop_correlations();
|
|
1362
|
+
* ```
|
|
1363
|
+
*
|
|
1364
|
+
* @see {@link start_correlations}
|
|
1365
|
+
*/
|
|
1064
1366
|
stop_correlations() {
|
|
1065
1367
|
if (this._correlation_interval) {
|
|
1066
1368
|
clearInterval(this._correlation_interval);
|