@bluelibs/runner 1.5.4 → 2.0.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.
Files changed (56) hide show
  1. package/README.md +299 -156
  2. package/dist/define.d.ts +1 -1
  3. package/dist/define.js +0 -1
  4. package/dist/define.js.map +1 -1
  5. package/dist/defs.d.ts +12 -8
  6. package/dist/globalEvents.js +45 -0
  7. package/dist/globalEvents.js.map +1 -1
  8. package/dist/globalResources.js +14 -0
  9. package/dist/globalResources.js.map +1 -1
  10. package/dist/models/DependencyProcessor.d.ts +1 -7
  11. package/dist/models/DependencyProcessor.js +31 -54
  12. package/dist/models/DependencyProcessor.js.map +1 -1
  13. package/dist/models/EventManager.d.ts +4 -0
  14. package/dist/models/EventManager.js.map +1 -1
  15. package/dist/models/ResourceInitializer.js +4 -2
  16. package/dist/models/ResourceInitializer.js.map +1 -1
  17. package/dist/models/Store.d.ts +2 -2
  18. package/dist/models/Store.js.map +1 -1
  19. package/dist/models/TaskRunner.js +28 -16
  20. package/dist/models/TaskRunner.js.map +1 -1
  21. package/dist/run.js +1 -1
  22. package/dist/run.js.map +1 -1
  23. package/package.json +1 -1
  24. package/src/__tests__/benchmark/benchmark.test.ts +9 -7
  25. package/src/__tests__/errors.test.ts +0 -13
  26. package/src/__tests__/globalEvents.test.ts +53 -28
  27. package/src/__tests__/index.ts +0 -1
  28. package/src/__tests__/models/EventManager.test.ts +1 -0
  29. package/src/__tests__/run.test.ts +140 -109
  30. package/src/__tests__/typesafety.test.ts +17 -16
  31. package/src/define.ts +3 -4
  32. package/src/defs.ts +35 -22
  33. package/src/globalEvents.ts +53 -0
  34. package/src/globalResources.ts +17 -0
  35. package/src/models/DependencyProcessor.ts +45 -80
  36. package/src/models/EventManager.ts +4 -0
  37. package/src/models/ResourceInitializer.ts +4 -2
  38. package/src/models/Store.ts +3 -2
  39. package/src/models/TaskRunner.ts +51 -28
  40. package/src/run.ts +1 -1
  41. package/dist/DependencyProcessor.d.ts +0 -49
  42. package/dist/DependencyProcessor.js +0 -178
  43. package/dist/DependencyProcessor.js.map +0 -1
  44. package/dist/EventManager.d.ts +0 -17
  45. package/dist/EventManager.js +0 -73
  46. package/dist/EventManager.js.map +0 -1
  47. package/dist/ResourceInitializer.d.ts +0 -13
  48. package/dist/ResourceInitializer.js +0 -54
  49. package/dist/ResourceInitializer.js.map +0 -1
  50. package/dist/Store.d.ts +0 -90
  51. package/dist/Store.js +0 -291
  52. package/dist/Store.js.map +0 -1
  53. package/dist/TaskRunner.d.ts +0 -25
  54. package/dist/TaskRunner.js +0 -96
  55. package/dist/TaskRunner.js.map +0 -1
  56. package/src/__tests__/run.hooks.test.ts +0 -110
package/README.md CHANGED
@@ -4,6 +4,7 @@
4
4
  <a href="https://github.com/bluelibs/runner/actions/workflows/ci.yml"><img src="https://github.com/bluelibs/runner/actions/workflows/ci.yml/badge.svg?branch=main" alt="Build Status" /></a>
5
5
  <a href="https://coveralls.io/github/bluelibs/runner?branch=main"><img src="https://coveralls.io/repos/github/bluelibs/runner/badge.svg?branch=main" alt="Coverage Status" /></a>
6
6
  <a href="https://bluelibs.github.io/runner/" target="_blank"><img src="https://img.shields.io/badge/read-typedocs-blue" alt="Docs" /></a>
7
+ <a href="https://github.com/bluelibs/runner" target="_blank"><img src="https://img.shields.io/badge/github-blue" alt="GitHub" /></a>
7
8
  </p>
8
9
 
9
10
  - [View the documentation page here](https://bluelibs.github.io/runner/).
@@ -244,7 +245,7 @@ const root = resource({
244
245
  });
245
246
  ```
246
247
 
247
- There are only 2 recommended ways to listen to events:
248
+ To listen to events you have to create a task.
248
249
 
249
250
  ### `task.on` property
250
251
 
@@ -277,9 +278,9 @@ const app = resource({
277
278
  });
278
279
  ```
279
280
 
280
- ### `resource.hooks` property
281
+ ### wildcard events
281
282
 
282
- This can only be applied to a `resource()`.
283
+ You can listen to all events by using the wildcard `*`.
283
284
 
284
285
  ```ts
285
286
  import { task, resource, run, event, global } from "@bluelibs/runner";
@@ -288,69 +289,24 @@ const afterRegisterEvent = event<{ userId: string }>({
288
289
  id: "app.user.registered",
289
290
  });
290
291
 
291
- const root = resource({
292
- id: "app",
293
- register: [afterRegisterEvent],
294
- dependencies: {},
295
- hooks: [
296
- {
297
- event: global.events.afterInit,
298
- order: -1000, // event priority, the lower the number, the sooner it will run.
299
- async run(event, deps) {
300
- // both dependencies and event are properly infered through typescript
301
- console.log("User has been registered!");
302
- },
303
- },
304
- ],
305
- async init(_, deps) {
306
- await deps.afterRegisterEvent({ userId: "XXX" });
292
+ const logAllEventsTask = task({
293
+ id: "app.tasks.logAllEvents",
294
+ on: "*",
295
+ run(event) {
296
+ console.log("Event detected", event.id, event.data);
307
297
  },
308
298
  });
309
- ```
310
-
311
- #### wildcard events
312
-
313
- You can listen to all events by using the wildcard `*`.
314
-
315
- ```ts
316
- import { task, resource, run, event, global } from "@bluelibs/runner";
317
-
318
- const afterRegisterEvent = event<{ userId: string }>({
319
- id: "app.user.registered",
320
- });
321
299
 
322
300
  const root = resource({
323
301
  id: "app",
324
- register: [afterRegisterEvent],
302
+ register: [afterRegisterEvent, logAllEventsTask],
325
303
  dependencies: {},
326
- hooks: [
327
- {
328
- event: "*",
329
- async run(event, deps) {
330
- console.log(
331
- "Generic event detected",
332
- event.id,
333
- event.data,
334
- event.timestamp
335
- );
336
- },
337
- },
338
- ],
339
304
  async init(_, deps) {
340
305
  deps.afterRegisterEvent({ userId: "XXX" });
341
306
  },
342
307
  });
343
308
  ```
344
309
 
345
- When using hooks, inside resource() you benefit of autocompletion, in order to keep things clean, if your hooks become large and long consider switching to tasks and `on`. This is a more explicit way to listen to events, and your resource registers them.
346
-
347
- The hooks from a `resource` are mostly used for configuration, and blending in the system.
348
-
349
- ### When to use either?
350
-
351
- - `hooks` are for resources to extend each other, compose functionalities, they are mostly used for configuration and blending in the system.
352
- - `on` is for when you want to perform a task when something happens, like send an email, begin processing something, etc.
353
-
354
310
  ## Middleware
355
311
 
356
312
  Middleware intercepts the execution of tasks or the initialization of resources, providing a powerful means to enhance functionality. The order in which middleware is registered dictates its execution priority: the first middleware registered is the first to run, while the last middleware in the middleware array at the task level is the closest to the task itself, executing just before the task completes. (Imagine an onion if you will, with the task at the core.)
@@ -669,41 +625,237 @@ run();
669
625
 
670
626
  ## Global Events
671
627
 
672
- ### Task level
628
+ You can listen to all events by using the wildcard `*`. However, keep in mind that to avoid infinite recursion, all the events coming from the same source will be ignored.
629
+
630
+ At the same time, if a task is listening to all events such as `beforeRun`, since it's a task, triggering `beforeRun` will lead to infinite recursion, this is why we ignore emitting the same event from the same source.
631
+
632
+ This guide outlines the key global events that can be used throughout your application to hook into resource and task lifecycle moments. These events help monitor initialization, execution, and errors, making your system more resilient and traceable.
633
+
634
+ ### Overview
635
+
636
+ Global events are categorized into:
637
+
638
+ - **Initialization events**: Before and after a resource or task is initialized.
639
+ - **Execution events**: Before and after a task runs.
640
+ - **Error events**: Handling errors for both tasks and resources.
641
+
642
+ ### Events in Tasks
643
+
644
+ #### `global.tasks.beforeRun`
645
+
646
+ This event is triggered just before a task is executed. It allows you to inspect or modify the input to the task.
647
+
648
+ ##### Example:
649
+
650
+ ```ts
651
+ task({
652
+ id: "logBeforeRun",
653
+ on: globalEvents.tasks.beforeRun, // Listening to the beforeRun event
654
+ run(event) {
655
+ console.log("Task is about to run with input:", event.data.input);
656
+ },
657
+ });
658
+ ```
659
+
660
+ **Use Case**: You can use this event to log input data or modify it before the task execution.
661
+
662
+ #### `global.tasks.afterRun`
663
+
664
+ This event fires immediately after a task finishes. It provides access to both the task input and the result (output).
665
+
666
+ ##### Example:
667
+
668
+ ```ts
669
+ task({
670
+ id: "logAfterRun",
671
+ on: globalEvents.tasks.afterRun, // Listening to the afterRun event
672
+ run(event) {
673
+ console.log(
674
+ "Task completed. Input:",
675
+ event.data.input,
676
+ "Output:",
677
+ event.data.output
678
+ );
679
+ },
680
+ });
681
+ ```
682
+
683
+ **Use Case**: Useful for logging or post-processing based on the task's output.
684
+
685
+ #### `global.tasks.onError`
686
+
687
+ If an error occurs during the execution of a task, this event is triggered. You can log or suppress the error.
688
+
689
+ ##### Example:
690
+
691
+ ```ts
692
+ task({
693
+ id: "handleTaskError",
694
+ on: globalEvents.tasks.onError, // Listening to the onError event
695
+ run(event) {
696
+ console.error("Error occurred:", event.data.error);
697
+ event.data.suppress(); // Optionally suppress the error to prevent propagation
698
+ },
699
+ });
700
+ ```
701
+
702
+ **Use Case**: Error handling logic for specific tasks. For example, you may want to send alerts when a task fails.
703
+
704
+ ### Events in Resources
705
+
706
+ #### `global.resources.beforeInit`
707
+
708
+ This event is triggered before a resource starts its initialization. It allows inspection or modification of the configuration before the resource is fully initialized.
709
+
710
+ ##### Example:
711
+
712
+ ```ts
713
+ task({
714
+ id: "logBeforeResourceInit",
715
+ on: globalEvents.resources.beforeInit, // Listening to beforeInit event for resources
716
+ run(event) {
717
+ console.log("Initializing resource with config:", event.data.config);
718
+ },
719
+ });
720
+ ```
721
+
722
+ **Use Case**: Logging or validating the resource's configuration before initialization.
723
+
724
+ #### `global.resources.afterInit`
725
+
726
+ This event fires after a resource is initialized, giving access to the initialization result.
727
+
728
+ ##### Example:
729
+
730
+ ```ts
731
+ task({
732
+ id: "logAfterResourceInit",
733
+ on: globalEvents.resources.afterInit, // Listening to afterInit event
734
+ run(event) {
735
+ console.log("Resource initialized with value:", event.data.value);
736
+ },
737
+ });
738
+ ```
739
+
740
+ **Use Case**: Post-processing or logging resource initialization details.
741
+
742
+ #### `global.resources.onError`
743
+
744
+ If an error occurs during resource initialization, this event is triggered. You can log or handle the error.
745
+
746
+ ##### Example:
747
+
748
+ ```ts
749
+ task({
750
+ id: "handleResourceError",
751
+ on: globalEvents.resources.onError, // Listening to resource onError event
752
+ run(event) {
753
+ console.error("Resource initialization error:", event.data.error);
754
+ event.data.suppress(); // Optionally suppress the error to prevent propagation
755
+ },
756
+ });
757
+ ```
758
+
759
+ **Use Case**: Error handling for critical resources, allowing for fallback mechanisms or error logging.
760
+
761
+ #### Common Usage Pattern
762
+
763
+ To make use of these events, you will typically define tasks that respond to these global events. These tasks can then be registered in your main application resource to handle events for resources and tasks alike.
764
+
765
+ #### Example of registering event-handling tasks:
766
+
767
+ ```ts
768
+ const app = resource({
769
+ id: "app",
770
+ register: [
771
+ logBeforeRun,
772
+ logAfterRun,
773
+ handleTaskError,
774
+ logBeforeResourceInit,
775
+ logAfterResourceInit,
776
+ handleResourceError,
777
+ ],
778
+ });
779
+
780
+ run(app);
781
+ ```
782
+
783
+ This structure helps you create a centralized and modular approach to manage events and handle tasks and resource lifecycles in your system.
784
+
785
+ ### Available Global Events
786
+
787
+ Here’s a summary of all the global events you can listen to:
788
+
789
+ - `global.beforeInit`: Triggered before any resource is initialized.
790
+ - `global.afterInit`: Triggered after any resource is initialized.
791
+ - `global.log`: Used for logging across the system.
792
+ - **Task-specific events**:
793
+ - `global.tasks.beforeRun`: Fired before a task begins execution.
794
+ - `global.tasks.afterRun`: Fired after a task completes.
795
+ - `global.tasks.onError`: Fired if a task encounters an error.
796
+ - **Resource-specific events**:
797
+ - `global.resources.beforeInit`: Fired before a resource is initialized.
798
+ - `global.resources.afterInit`: Fired after a resource is initialized.
799
+ - `global.resources.onError`: Fired if an error occurs during resource initialization.
800
+
801
+ This modular event system helps in building more reactive and error-tolerant applications.
802
+
803
+ ### Individual Task level
804
+
805
+ When creating tasks or resources we also create lifecycle events for them stored in `events` property.
673
806
 
674
807
  ```ts
675
808
  import { task, run, event } from "@bluelibs/runner";
676
809
 
810
+ // Define the task
677
811
  const helloWorld = task({
678
812
  id: "app.helloWorld",
813
+ async run() {
814
+ // Task logic here
815
+ return "Hello World!";
816
+ },
817
+ });
818
+
819
+ // Define the tasks for beforeRun, afterRun, and onError using the `on` property
820
+ const beforeHelloWorldTask = task({
821
+ id: "app.helloWorld.beforeRun",
822
+ on: helloWorld.events.beforeRun, // Listening to beforeRun event
823
+ async run(event) {
824
+ const input = event.data.input; // Handle the input before task runs
825
+ console.log("Before run:", input);
826
+ },
827
+ });
828
+
829
+ const afterHelloWorldTask = task({
830
+ id: "app.helloWorld.afterRun",
831
+ on: helloWorld.events.afterRun, // Listening to afterRun event
832
+ async run(event) {
833
+ const output = event.data.output; // Handle the output after task runs
834
+ console.log("After run:", output);
835
+ },
836
+ });
837
+
838
+ const helloWorldErrorTask = task({
839
+ id: "app.helloWorld.onError",
840
+ on: helloWorld.events.onError, // Listening to onError event
841
+ async run(event) {
842
+ const error = event.data.error; // Handle errors during task execution
843
+ console.error("Error:", error);
844
+ },
679
845
  });
680
846
 
681
- // Each task and constant have their own events
847
+ // Register all tasks to the app
682
848
  const app = resource({
683
849
  id: "app",
684
- register: [helloWorld],
685
- hooks: [
686
- {
687
- event: helloWorld.events.beforeRun,
688
- async run(event, deps) {
689
- event.data.input; // read the input
690
- },
691
- },
692
- {
693
- event: helloWorld.events.afterRun,
694
- async run(event, deps) {
695
- event.data.output; // you can read the input or output
696
- },
697
- },
698
- {
699
- event: helloWorld.events.onError,
700
- async run(event, deps) {
701
- event.data.error; // read the error that happened during execution
702
- },
703
- },
850
+ register: [
851
+ helloWorld,
852
+ beforeHelloWorldTask,
853
+ afterHelloWorldTask,
854
+ helloWorldErrorTask,
704
855
  ],
705
856
  });
706
857
 
858
+ // Run the app
707
859
  run(app);
708
860
  ```
709
861
 
@@ -712,42 +864,56 @@ run(app);
712
864
  ```ts
713
865
  import { task, run, event } from "@bluelibs/runner";
714
866
 
715
- const businessData = {
716
- pricePerSubscription: 9.99,
717
- };
718
-
867
+ // Define the resource
719
868
  const businessConfig = resource({
720
- id: "app.config",
721
- async init() {
722
- return businessData; // if you use it as a const you will have full typesafety
869
+ id: "app.businessConfig",
870
+ async init(config) {
871
+ // Business logic to initialize config
872
+ return { value: "Business Configuration Loaded" };
873
+ },
874
+ });
875
+
876
+ // Define tasks for handling events beforeInit, afterInit, and onError
877
+
878
+ const beforeInitTask = task({
879
+ id: "app.businessConfig.beforeInit",
880
+ on: businessConfig.events.beforeInit, // Listening to beforeInit event
881
+ async run(event) {
882
+ const config = event.data.config; // Handle the config input before resource initialization
883
+ console.log("Before init:", config);
884
+ },
885
+ });
886
+
887
+ const afterInitTask = task({
888
+ id: "app.businessConfig.afterInit",
889
+ on: businessConfig.events.afterInit, // Listening to afterInit event
890
+ async run(event) {
891
+ const value = event.data.value; // Handle the return value after resource initialization
892
+ console.log("After init:", value);
893
+ },
894
+ });
895
+
896
+ const businessConfigErrorTask = task({
897
+ id: "app.businessConfig.onError",
898
+ on: businessConfig.events.onError, // Listening to onError event
899
+ async run(event) {
900
+ const error = event.data.error; // Handle errors during resource initialization
901
+ console.error("Error during initialization:", error);
723
902
  },
724
903
  });
725
904
 
905
+ // Register all tasks and the businessConfig resource to the app
726
906
  const app = resource({
727
907
  id: "app",
728
- register: [businessConfig],
729
- hooks: [
730
- {
731
- event: businessConfig.events.beforeInit,
732
- async run(event, deps) {
733
- event.data.config; // read the input
734
- },
735
- },
736
- {
737
- event: businessConfig.events.afterInit,
738
- async run(event, deps) {
739
- event.data.value; // you can read the returned value of the resource
740
- },
741
- },
742
- {
743
- event: businessConfig.events.onError,
744
- async run(event, deps) {
745
- event.data.error; // read the error that happened during initialization
746
- },
747
- },
908
+ register: [
909
+ businessConfig,
910
+ beforeInitTask,
911
+ afterInitTask,
912
+ businessConfigErrorTask,
748
913
  ],
749
914
  });
750
915
 
916
+ // Run the app
751
917
  run(app);
752
918
  ```
753
919
 
@@ -843,7 +1009,7 @@ const app = resource({
843
1009
  });
844
1010
  ```
845
1011
 
846
- However, other resources might need to modify this dynamically as extensions. This is where hooks become valuable.
1012
+ However, other resources might need to modify this dynamically as extensions. This is where events become valuable.
847
1013
 
848
1014
  ```ts
849
1015
  import { resource, run, event } from "@bluelibs/runner";
@@ -853,35 +1019,27 @@ type SecurityOptions = {
853
1019
  };
854
1020
 
855
1021
  const securityResource = resource({
856
- id: "app.security",
857
- async init(config: SecurityOptions) {
858
- let hasher = config.hashFunction;
859
- return {
860
- setHasher: (hashFunction: (input: string) => string) => {
861
- hasher = hashFunction;
862
- },
863
- hash: (input: string) => hasher(input),
864
- };
1022
+ /* Same as above, but create a setHasher method */
1023
+ });
1024
+ const afterSecurityInitTask = task({
1025
+ id: "app.security.afterInit",
1026
+ on: securityResource.events.afterInit, // Listening to afterInit event
1027
+ async run(event, deps) {
1028
+ const { config, value } = event.data;
1029
+ const security = value;
1030
+
1031
+ // Custom hasher implementation
1032
+ security.setHasher((input) => {
1033
+ // Implement custom hashing logic here
1034
+ console.log("Hashing input:", input);
1035
+ });
865
1036
  },
866
1037
  });
867
1038
 
1039
+ // Register the security resource and the afterInit task in the app
868
1040
  const app = resource({
869
1041
  id: "app",
870
- register: [securityResource],
871
- hooks: [
872
- {
873
- // careful when you listen on such events and need dependencies, you might not have them computed yet due to how early these events happen in the system.
874
- event: securityResource.events.afterInit,
875
- async run(event, deps) {
876
- const { config, value } = event.data;
877
- const security = value;
878
-
879
- security.setHasher((input) => {
880
- // custom implementation here.
881
- });
882
- },
883
- },
884
- ],
1042
+ register: [securityResource, afterSecurityInitTask],
885
1043
  });
886
1044
  ```
887
1045
 
@@ -910,18 +1068,21 @@ const securityResource = resource({
910
1068
  },
911
1069
  });
912
1070
 
1071
+ // Define securityResource and securityConfigurationPhaseEvent as needed
1072
+
1073
+ const securityConfigTask = task({
1074
+ id: "app.security.config",
1075
+ on: securityConfigurationPhaseEvent, // Listening to securityConfigurationPhaseEvent
1076
+ async run(event, deps) {
1077
+ const { config } = event.data; // config is SecurityOptions
1078
+ config.setHasher(newHashFunction); // Apply the new hash function
1079
+ },
1080
+ });
1081
+
1082
+ // Register the security resource and configuration task in the app
913
1083
  const app = resource({
914
1084
  id: "app",
915
- register: [securityResource],
916
- hooks: [
917
- {
918
- event: securityConfigurationPhaseEvent,
919
- async run(event, deps) {
920
- const { config } = event.data; // config is SecurityOptions
921
- config.setHasher(newHashFunction);
922
- },
923
- },
924
- ],
1085
+ register: [securityResource, securityConfigTask],
925
1086
  });
926
1087
  ```
927
1088
 
@@ -1018,24 +1179,6 @@ const app = resource({
1018
1179
  // Now your app will print all logs
1019
1180
  ```
1020
1181
 
1021
- You can also achieve this using hooks:
1022
-
1023
- ```ts
1024
- resource({
1025
- id: "root",
1026
- hooks: [
1027
- {
1028
- // after logger gets initialised as a resource, I'm going to set the print threshold
1029
- event: logger.events.afterInit,
1030
- async run(event) {
1031
- const logger = event.data; // do not depend on the logger
1032
- logger.setPrintThreshold("trace");
1033
- },
1034
- },
1035
- ],
1036
- });
1037
- ```
1038
-
1039
1182
  The logger’s log() function is asynchronous because it handles events. If you want to prevent your system from waiting for log operations to complete, simply omit the await when calling log(). This is useful if you have listeners that send logs to external log storage systems.
1040
1183
 
1041
1184
  Additionally, there is a `global.events.log` event available. You can use this event both to emit log messages and to listen for all log activities.
package/dist/define.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { ITask, ITaskDefinition, IResource, IResourceWithConfig, IResourceDefinition, IEventDefinition, IMiddlewareDefinition, DependencyMapType, IMiddleware, IEventDefinitionConfig } from "./defs";
2
- export declare function defineTask<Input = undefined, Output extends Promise<any> = any, Deps extends DependencyMapType = any, Test = any>(taskConfig: ITaskDefinition<Input, Output, Deps, Test>): ITask<Input, Output, Deps, Test>;
2
+ export declare function defineTask<Input = undefined, Output extends Promise<any> = any, Deps extends DependencyMapType = any, TOn extends "*" | IEventDefinition | undefined = undefined>(taskConfig: ITaskDefinition<Input, Output, Deps, TOn>): ITask<Input, Output, Deps, TOn>;
3
3
  export declare function defineResource<TConfig = void, TValue = any, TDeps extends DependencyMapType = {}, THooks = any>(constConfig: IResourceDefinition<TConfig, TValue, TDeps, THooks>): IResource<TConfig, TValue, TDeps>;
4
4
  export declare function defineEvent<TPayload = any>(config: IEventDefinitionConfig<TPayload>): IEventDefinition<TPayload>;
5
5
  export declare function defineMiddleware<TDeps extends DependencyMapType = {}>(config: IMiddlewareDefinition<TDeps>): IMiddleware<TDeps>;
package/dist/define.js CHANGED
@@ -39,7 +39,6 @@ function defineResource(constConfig) {
39
39
  [defs_1.symbols.resource]: true,
40
40
  id: constConfig.id,
41
41
  dependencies: constConfig.dependencies,
42
- hooks: constConfig.hooks || [],
43
42
  dispose: constConfig.dispose,
44
43
  register: constConfig.register || [],
45
44
  overrides: constConfig.overrides || [],
@@ -1 +1 @@
1
- {"version":3,"file":"define.js","sourceRoot":"","sources":["../src/define.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"define.js","sourceRoot":"","sources":["../src/define.ts"],"names":[],"mappings":"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"}
package/dist/defs.d.ts CHANGED
@@ -25,7 +25,7 @@ export interface IEventMeta extends IMeta {
25
25
  }
26
26
  export interface IMiddlewareMeta extends IMeta {
27
27
  }
28
- export type DependencyMapType = Record<string, ITask<any, any, any> | IResource<any, any, any> | IEventDefinition<any>>;
28
+ export type DependencyMapType = Record<string, ITask<any, any, any, any> | IResource<any, any, any> | IEventDefinition<any>>;
29
29
  type ExtractTaskInput<T> = T extends ITask<infer I, any, infer D> ? I : never;
30
30
  type ExtractTaskOutput<T> = T extends ITask<any, infer O, infer D> ? O : never;
31
31
  type ExtractResourceValue<T> = T extends IResource<any, infer V, infer D> ? V : never;
@@ -37,22 +37,28 @@ export type DependencyValueType<T> = T extends ITask<any, any, any> ? TaskDepend
37
37
  export type DependencyValuesType<T extends DependencyMapType> = {
38
38
  [K in keyof T]: DependencyValueType<T[K]>;
39
39
  };
40
- export type RegisterableItems = IResourceWithConfig<any> | IResource<void, any, any> | ITaskDefinition | IMiddlewareDefinition | IEventDefinition;
41
- export interface ITaskDefinition<TInput = any, TOutput extends Promise<any> = any, TDependencies extends DependencyMapType = {}, TEventDefinitionInput = null> {
40
+ type Optional<T> = {
41
+ [K in keyof T]?: T[K];
42
+ };
43
+ type IsVoid<T> = [T] extends [void] ? true : false;
44
+ type IsOptional<T> = undefined extends T ? true : false;
45
+ type OptionalOrVoidOrAnything<T> = IsVoid<T> extends true ? void : IsOptional<T> extends true ? Optional<T> : T;
46
+ export type RegisterableItems<T = any> = IResourceWithConfig<any> | IResource<void, any, any> | IResource<OptionalOrVoidOrAnything<T>, any, any> | ITaskDefinition<any, any, any, any> | IMiddlewareDefinition<any> | IEventDefinition<any>;
47
+ export interface ITaskDefinition<TInput = any, TOutput extends Promise<any> = any, TDependencies extends DependencyMapType = {}, TOn extends "*" | IEventDefinition<any> | undefined = undefined> {
42
48
  id: string;
43
49
  dependencies?: TDependencies | (() => TDependencies);
44
50
  middleware?: IMiddlewareDefinition[];
45
51
  /**
46
52
  * Listen to events in a simple way
47
53
  */
48
- on?: IEventDefinition<TEventDefinitionInput>;
54
+ on?: TOn;
49
55
  /**
50
56
  * This makes sense only when `on` is specified to provide the order of the execution.
51
57
  * The event with the lowest order will be executed first.
52
58
  */
53
59
  listenerOrder?: number;
54
60
  meta?: ITaskMeta;
55
- run: (input: TEventDefinitionInput extends null ? TInput : TEventDefinitionInput, dependencies: DependencyValuesType<TDependencies>) => TOutput;
61
+ run: (input: TOn extends undefined ? TInput : IEvent<ExtractEventParams<TOn>>, dependencies: DependencyValuesType<TDependencies>) => TOutput;
56
62
  }
57
63
  export type BeforeRunEventPayload<TInput> = {
58
64
  input: TInput;
@@ -78,7 +84,7 @@ export type AfterInitEventPayload<TConfig, TValue> = {
78
84
  /**
79
85
  * This is the response after the definition has been prepared. TODO: better naming?
80
86
  */
81
- export interface ITask<TInput = any, TOutput extends Promise<any> = any, TDependencies extends DependencyMapType = {}, TEventDefinitionInput = null> extends ITaskDefinition<TInput, TOutput, TDependencies, TEventDefinitionInput> {
87
+ export interface ITask<TInput = any, TOutput extends Promise<any> = any, TDependencies extends DependencyMapType = {}, TOn extends "*" | IEventDefinition<any> | undefined = undefined> extends ITaskDefinition<TInput, TOutput, TDependencies, TOn> {
82
88
  dependencies: TDependencies | (() => TDependencies);
83
89
  computedDependencies?: DependencyValuesType<TDependencies>;
84
90
  middleware: IMiddlewareDefinition[];
@@ -94,7 +100,6 @@ export interface ITask<TInput = any, TOutput extends Promise<any> = any, TDepend
94
100
  export interface IResourceDefinition<TConfig = any, TValue = unknown, TDependencies extends DependencyMapType = {}, THooks = any, TRegisterableItems = any> {
95
101
  id: string;
96
102
  dependencies?: TDependencies | ((config: TConfig) => TDependencies);
97
- hooks?: IHookDefinition<TDependencies, THooks>[] | ((config: TConfig) => IHookDefinition<TDependencies, THooks>[]);
98
103
  register?: Array<RegisterableItems> | ((config: TConfig) => Array<RegisterableItems>);
99
104
  init?: (config: TConfig, dependencies: DependencyValuesType<TDependencies>) => Promise<TValue>;
100
105
  /**
@@ -121,7 +126,6 @@ export interface IResource<TConfig = void, TValue = any, TDependencies extends D
121
126
  afterInit: IEventDefinition<AfterInitEventPayload<TConfig, TValue>>;
122
127
  onError: IEventDefinition<OnErrorEventPayload>;
123
128
  };
124
- hooks: IHookDefinition<TDependencies>[] | ((config: TConfig) => IHookDefinition<TDependencies>[]);
125
129
  overrides: Array<IResource | ITask | IMiddleware | IResourceWithConfig>;
126
130
  middleware: IMiddlewareDefinition[];
127
131
  }