@bluelibs/runner 3.0.0 → 3.1.1
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/README.md +272 -12
- package/dist/define.d.ts +3 -3
- package/dist/define.js +39 -14
- package/dist/define.js.map +1 -1
- package/dist/defs.d.ts +60 -45
- package/dist/defs.js +3 -1
- package/dist/defs.js.map +1 -1
- package/dist/errors.d.ts +5 -5
- package/dist/errors.js +6 -5
- package/dist/errors.js.map +1 -1
- package/dist/globals/globalEvents.d.ts +11 -11
- package/dist/globals/globalMiddleware.d.ts +1 -1
- package/dist/globals/globalResources.d.ts +3 -3
- package/dist/globals/middleware/cache.middleware.d.ts +2 -2
- package/dist/globals/middleware/cache.middleware.js.map +1 -1
- package/dist/globals/resources/queue.resource.d.ts +2 -2
- package/dist/globals/resources/queue.resource.js.map +1 -1
- package/dist/index.d.ts +13 -13
- package/dist/models/DependencyProcessor.d.ts +4 -4
- package/dist/models/DependencyProcessor.js +2 -2
- package/dist/models/DependencyProcessor.js.map +1 -1
- package/dist/models/EventManager.d.ts +5 -5
- package/dist/models/EventManager.js.map +1 -1
- package/dist/models/Logger.d.ts +1 -1
- package/dist/models/Logger.js +29 -27
- package/dist/models/Logger.js.map +1 -1
- package/dist/models/OverrideManager.d.ts +2 -2
- package/dist/models/OverrideManager.js.map +1 -1
- package/dist/models/ResourceInitializer.js +3 -1
- package/dist/models/ResourceInitializer.js.map +1 -1
- package/dist/models/Store.d.ts +8 -8
- package/dist/models/Store.js.map +1 -1
- package/dist/models/StoreConstants.d.ts +2 -2
- package/dist/models/StoreRegistry.d.ts +8 -8
- package/dist/models/StoreRegistry.js +1 -1
- package/dist/models/StoreRegistry.js.map +1 -1
- package/dist/models/StoreValidator.d.ts +2 -2
- package/dist/models/StoreValidator.js +1 -1
- package/dist/models/StoreValidator.js.map +1 -1
- package/dist/models/TaskRunner.d.ts +1 -1
- package/dist/tools/getCallerFile.d.ts +9 -1
- package/dist/tools/getCallerFile.js +41 -0
- package/dist/tools/getCallerFile.js.map +1 -1
- package/package.json +1 -1
- package/src/__tests__/models/EventManager.test.ts +48 -46
- package/src/__tests__/recursion/README.md +3 -0
- package/src/__tests__/recursion/a.resource.ts +25 -0
- package/src/__tests__/recursion/b.resource.ts +33 -0
- package/src/__tests__/recursion/c.resource.ts +18 -0
- package/src/__tests__/run.anonymous.test.ts +679 -0
- package/src/__tests__/run.dynamic-register-and-dependencies.test.ts +1185 -0
- package/src/__tests__/run.middleware.test.ts +146 -0
- package/src/__tests__/run.test.ts +1 -1
- package/src/__tests__/tools/getCallerFile.test.ts +117 -2
- package/src/__tests__/typesafety.test.ts +17 -2
- package/src/define.ts +47 -22
- package/src/defs.ts +77 -90
- package/src/errors.ts +13 -10
- package/src/globals/middleware/cache.middleware.ts +1 -1
- package/src/globals/resources/queue.resource.ts +1 -1
- package/src/models/DependencyProcessor.ts +7 -10
- package/src/models/EventManager.ts +25 -14
- package/src/models/Logger.ts +51 -39
- package/src/models/OverrideManager.ts +3 -3
- package/src/models/ResourceInitializer.ts +3 -1
- package/src/models/Store.ts +2 -2
- package/src/models/StoreRegistry.ts +28 -17
- package/src/models/StoreValidator.ts +13 -8
- package/src/models/TaskRunner.ts +1 -1
- package/src/tools/getCallerFile.ts +54 -2
package/README.md
CHANGED
|
@@ -63,7 +63,7 @@ const createUser = task({
|
|
|
63
63
|
const app = resource({
|
|
64
64
|
id: "app",
|
|
65
65
|
// Here you make the system aware of resources, tasks, middleware, and events.
|
|
66
|
-
register: [server, createUser],
|
|
66
|
+
register: [server.with({ port: 3000 }), createUser],
|
|
67
67
|
dependencies: { server, createUser },
|
|
68
68
|
init: async (_, { server, createUser }) => {
|
|
69
69
|
server.app.post("/users", async (req, res) => {
|
|
@@ -74,7 +74,7 @@ const app = resource({
|
|
|
74
74
|
});
|
|
75
75
|
|
|
76
76
|
// That's it. No webpack configs, no decorators, no XML.
|
|
77
|
-
const { dispose } = await run(app
|
|
77
|
+
const { dispose } = await run(app);
|
|
78
78
|
```
|
|
79
79
|
|
|
80
80
|
## The Big Four: Your New Building Blocks
|
|
@@ -530,6 +530,40 @@ const app = resource({
|
|
|
530
530
|
});
|
|
531
531
|
```
|
|
532
532
|
|
|
533
|
+
## Retrying Failed Operations
|
|
534
|
+
|
|
535
|
+
For when things go wrong, but you know they'll probably work if you just try again. The built-in retry middleware makes your tasks and resources more resilient to transient failures.
|
|
536
|
+
|
|
537
|
+
```typescript
|
|
538
|
+
import { globals } from "@bluelibs/runner";
|
|
539
|
+
|
|
540
|
+
const flakyApiCall = task({
|
|
541
|
+
id: "app.tasks.flakyApiCall",
|
|
542
|
+
middleware: [
|
|
543
|
+
globals.middleware.retry.with({
|
|
544
|
+
retries: 5, // Try up to 5 times
|
|
545
|
+
delayStrategy: (attempt) => 100 * Math.pow(2, attempt), // Exponential backoff
|
|
546
|
+
stopRetryIf: (error) => error.message === "Invalid credentials", // Don't retry auth errors
|
|
547
|
+
}),
|
|
548
|
+
],
|
|
549
|
+
run: async () => {
|
|
550
|
+
// This might fail due to network issues, rate limiting, etc.
|
|
551
|
+
return await fetchFromUnreliableService();
|
|
552
|
+
},
|
|
553
|
+
});
|
|
554
|
+
|
|
555
|
+
const app = resource({
|
|
556
|
+
id: "app",
|
|
557
|
+
register: [flakyApiCall],
|
|
558
|
+
});
|
|
559
|
+
```
|
|
560
|
+
|
|
561
|
+
The retry middleware can be configured with:
|
|
562
|
+
|
|
563
|
+
- `retries`: The maximum number of retry attempts (default: 3).
|
|
564
|
+
- `delayStrategy`: A function that returns the delay in milliseconds before the next attempt.
|
|
565
|
+
- `stopRetryIf`: A function to prevent retries for certain types of errors.
|
|
566
|
+
|
|
533
567
|
## Logging: Because Console.log Isn't Professional
|
|
534
568
|
|
|
535
569
|
_The structured logging system that actually makes debugging enjoyable_
|
|
@@ -928,16 +962,6 @@ await paymentLogger.info("Processing payment", { data: paymentData });
|
|
|
928
962
|
await authLogger.warn("Failed login attempt", { data: { email, ip } });
|
|
929
963
|
```
|
|
930
964
|
|
|
931
|
-
### Common Pitfalls
|
|
932
|
-
|
|
933
|
-
1. **Logging sensitive data**: Never log passwords, tokens, or PII
|
|
934
|
-
2. **Over-logging in hot paths**: Check print thresholds for expensive operations
|
|
935
|
-
3. **Forgetting error objects**: Always include the original error when logging failures
|
|
936
|
-
4. **Poor log levels**: Don't use `error` for expected conditions
|
|
937
|
-
5. **Missing context**: Include relevant identifiers (user ID, request ID, etc.)
|
|
938
|
-
|
|
939
|
-
The Logger system is designed to be fast, flexible, and non-intrusive. Use it liberally - good logging is the difference between debugging hell and debugging heaven.
|
|
940
|
-
|
|
941
965
|
## Meta: Tagging Your Components
|
|
942
966
|
|
|
943
967
|
Sometimes you want to attach metadata to your tasks and resources for documentation, filtering, or middleware logic:
|
|
@@ -1060,6 +1084,140 @@ const advancedTask = task({
|
|
|
1060
1084
|
});
|
|
1061
1085
|
```
|
|
1062
1086
|
|
|
1087
|
+
### Dependency Patterns: Static vs Dynamic
|
|
1088
|
+
|
|
1089
|
+
Dependencies can be defined in two ways - as a static object or as a function that returns an object. Each approach has its use cases:
|
|
1090
|
+
|
|
1091
|
+
```typescript
|
|
1092
|
+
// Static dependencies (most common)
|
|
1093
|
+
const userService = resource({
|
|
1094
|
+
id: "app.services.user",
|
|
1095
|
+
dependencies: { database, logger }, // Object - evaluated immediately
|
|
1096
|
+
init: async (_, { database, logger }) => {
|
|
1097
|
+
// Dependencies are available here
|
|
1098
|
+
},
|
|
1099
|
+
});
|
|
1100
|
+
|
|
1101
|
+
// Dynamic dependencies (for circular references or conditional dependencies)
|
|
1102
|
+
const advancedService = resource({
|
|
1103
|
+
id: "app.services.advanced",
|
|
1104
|
+
// A function gives you the chance
|
|
1105
|
+
dependencies: (config) => ({
|
|
1106
|
+
// Config is what you receive when you register tise resource with .with()
|
|
1107
|
+
// So you can have conditional dependencies based on resource configuration as well.
|
|
1108
|
+
database,
|
|
1109
|
+
logger,
|
|
1110
|
+
conditionalService:
|
|
1111
|
+
process.env.NODE_ENV === "production" ? serviceA : serviceB,
|
|
1112
|
+
}), // Function - evaluated when needed
|
|
1113
|
+
register: (config) => [
|
|
1114
|
+
// Config is what you receive when you register the resource with .with()
|
|
1115
|
+
// Register dependencies dynamically
|
|
1116
|
+
process.env.NODE_ENV === "production"
|
|
1117
|
+
? serviceA.with({ config: "value" })
|
|
1118
|
+
: serviceB.with({ config: "value" }),
|
|
1119
|
+
],
|
|
1120
|
+
init: async (_, { database, logger, conditionalService }) => {
|
|
1121
|
+
// Same interface, different evaluation timing
|
|
1122
|
+
},
|
|
1123
|
+
});
|
|
1124
|
+
```
|
|
1125
|
+
|
|
1126
|
+
The function pattern essentially gives you "just-in-time" dependency resolution instead of "eager" dependency resolution, which provides more flexibility and better handles complex dependency scenarios that arise in real-world applications.
|
|
1127
|
+
|
|
1128
|
+
**Performance note**: Function-based dependencies have minimal overhead - they're only called once during dependency resolution.
|
|
1129
|
+
|
|
1130
|
+
### Handling Circular "Type" Dependencies: Breaking the Chain
|
|
1131
|
+
|
|
1132
|
+
Sometimes you'll run into circular type dependencies because of your file structure not necessarily because of a real circular dependency. TypeScript struggles with these, but there's a way to handle it gracefully.
|
|
1133
|
+
|
|
1134
|
+
#### The Problem: Self-Referencing Types
|
|
1135
|
+
|
|
1136
|
+
Consider these resources that create a circular dependency:
|
|
1137
|
+
|
|
1138
|
+
```typescript
|
|
1139
|
+
// FILE: a.ts
|
|
1140
|
+
export const aResource = defineResource({
|
|
1141
|
+
dependencies: { b: bResource },
|
|
1142
|
+
// ... depends on B resource.
|
|
1143
|
+
});
|
|
1144
|
+
// For whatever reason, you decide to put the task in the same file.
|
|
1145
|
+
export const aTask = defineTask({
|
|
1146
|
+
dependencies: { a: aResource },
|
|
1147
|
+
});
|
|
1148
|
+
|
|
1149
|
+
// FILE: b.ts
|
|
1150
|
+
export const bResource = defineResource({
|
|
1151
|
+
id: "b.resource",
|
|
1152
|
+
dependencies: { c: cResource },
|
|
1153
|
+
});
|
|
1154
|
+
|
|
1155
|
+
// FILE: c.ts
|
|
1156
|
+
export const cResource = defineResource({
|
|
1157
|
+
id: "c.resource",
|
|
1158
|
+
dependencies: { aTask }, // Creates circular **type** dependency! Cannot infer types properly, even if the runner boots because there's no circular dependency.
|
|
1159
|
+
async init(_, { aTask }) {
|
|
1160
|
+
return `C depends on aTask`;
|
|
1161
|
+
},
|
|
1162
|
+
});
|
|
1163
|
+
```
|
|
1164
|
+
|
|
1165
|
+
A depends B depends C depends ATask. No circular dependency, yet Typescript struggles with these, but there's a way to handle it gracefully.
|
|
1166
|
+
|
|
1167
|
+
#### The Solution: Type Annotations
|
|
1168
|
+
|
|
1169
|
+
The fix is to explicitly type the resource that completes the circle using a simple assertion `IResource<Config, ReturnType>`. This breaks the TypeScript inference chain while maintaining runtime functionality:
|
|
1170
|
+
|
|
1171
|
+
```typescript
|
|
1172
|
+
// c.resource.ts - The key change
|
|
1173
|
+
import { IResource } from "../../defs";
|
|
1174
|
+
|
|
1175
|
+
export const cResource = defineResource({
|
|
1176
|
+
id: "c.resource",
|
|
1177
|
+
dependencies: { a: aResource },
|
|
1178
|
+
async init(_, { a }) {
|
|
1179
|
+
return `C depends on ${a}`;
|
|
1180
|
+
},
|
|
1181
|
+
}) as IResource<void, string>; // void because it has no config, string because it returns a string
|
|
1182
|
+
```
|
|
1183
|
+
|
|
1184
|
+
#### Why This Works
|
|
1185
|
+
|
|
1186
|
+
- **Runtime**: The circular dependency still works at runtime because the framework resolves dependencies dynamically
|
|
1187
|
+
- **TypeScript**: The explicit type annotation prevents TypeScript from trying to infer the return type based on the circular chain
|
|
1188
|
+
- **Type Safety**: You still get full type safety by explicitly declaring the return type (`string` in this example)
|
|
1189
|
+
|
|
1190
|
+
#### Best Practices
|
|
1191
|
+
|
|
1192
|
+
1. **Identify the "leaf" resource**: Choose the resource that logically should break the chain (often the one that doesn't need complex type inference)
|
|
1193
|
+
2. **Use explicit typing**: Add the `IResource<Dependencies, ReturnType>` type annotation
|
|
1194
|
+
3. **Document the decision**: Add a comment explaining why the explicit typing is needed
|
|
1195
|
+
4. **Consider refactoring**: If you have many circular dependencies, consider if your architecture could be simplified
|
|
1196
|
+
|
|
1197
|
+
#### Example with Dependencies
|
|
1198
|
+
|
|
1199
|
+
If your resource has dependencies, include them in the type:
|
|
1200
|
+
|
|
1201
|
+
```typescript
|
|
1202
|
+
type MyDependencies = {
|
|
1203
|
+
someService: SomeServiceType;
|
|
1204
|
+
anotherResource: AnotherResourceType;
|
|
1205
|
+
};
|
|
1206
|
+
|
|
1207
|
+
export const problematicResource = defineResource({
|
|
1208
|
+
id: "problematic.resource",
|
|
1209
|
+
dependencies: {
|
|
1210
|
+
/* ... */
|
|
1211
|
+
},
|
|
1212
|
+
async init(config, deps) {
|
|
1213
|
+
// Your logic here
|
|
1214
|
+
return someComplexObject;
|
|
1215
|
+
},
|
|
1216
|
+
}) as IResource<MyDependencies, ComplexReturnType>;
|
|
1217
|
+
```
|
|
1218
|
+
|
|
1219
|
+
This pattern allows you to maintain clean, type-safe code while handling the inevitable circular dependencies that arise in complex applications.
|
|
1220
|
+
|
|
1063
1221
|
## Real-World Example: The Complete Package
|
|
1064
1222
|
|
|
1065
1223
|
Here's a more realistic application structure that shows everything working together:
|
|
@@ -1259,6 +1417,7 @@ const testDatabase = resource({
|
|
|
1259
1417
|
init: async () => new MemoryDatabase(), // In-memory test database
|
|
1260
1418
|
});
|
|
1261
1419
|
|
|
1420
|
+
// Just like a shaworma wrap!
|
|
1262
1421
|
const testApp = resource({
|
|
1263
1422
|
id: "test.app",
|
|
1264
1423
|
register: [productionApp],
|
|
@@ -1670,6 +1829,107 @@ async function processBatch(items: any[]) {
|
|
|
1670
1829
|
- **Ignoring disposal**: Always dispose semaphores to prevent memory leaks
|
|
1671
1830
|
- **Wrong permit count**: Too few = slow, too many = defeats the purpose
|
|
1672
1831
|
|
|
1832
|
+
## Anonymous IDs: Because Naming Things Is Hard
|
|
1833
|
+
|
|
1834
|
+
One of our favorite quality-of-life features: **anonymous IDs**. Instead of manually naming every component, the framework can generate unique symbol-based identifiers based on your file path and variable name. It's like having a really good naming assistant who never gets tired.
|
|
1835
|
+
|
|
1836
|
+
### How Anonymous IDs Work
|
|
1837
|
+
|
|
1838
|
+
When you omit the `id` property, the framework generates a unique symbol based on file path. Takes up until first 'src' or 'node_modules' and generates based on the paths.
|
|
1839
|
+
|
|
1840
|
+
```typescript
|
|
1841
|
+
// In src/services/email.ts
|
|
1842
|
+
const emailService = resource({
|
|
1843
|
+
// Generated ID: Symbol('services.email.resource')
|
|
1844
|
+
init: async () => new EmailService(),
|
|
1845
|
+
});
|
|
1846
|
+
|
|
1847
|
+
// In src/tasks/user.ts
|
|
1848
|
+
const createUser = task({
|
|
1849
|
+
// Generated ID: Symbol('tasks.user.task')
|
|
1850
|
+
dependencies: { emailService },
|
|
1851
|
+
run: async (userData, { emailService }) => {
|
|
1852
|
+
// Business logic
|
|
1853
|
+
},
|
|
1854
|
+
});
|
|
1855
|
+
```
|
|
1856
|
+
|
|
1857
|
+
### Benefits of Anonymous IDs
|
|
1858
|
+
|
|
1859
|
+
1. **Less Bikeshedding**: No more debates about naming conventions
|
|
1860
|
+
2. **Automatic Uniqueness**: Guaranteed collision-free identifiers
|
|
1861
|
+
3. **Faster Prototyping**: Just write code, framework handles the rest
|
|
1862
|
+
4. **Refactor-Friendly**: Rename files/variables and IDs update automatically
|
|
1863
|
+
5. **Stack Trace Integration**: Error messages include helpful file locations
|
|
1864
|
+
|
|
1865
|
+
### When to Use Manual vs Anonymous IDs
|
|
1866
|
+
|
|
1867
|
+
| Use Case | Recommendation | Reason |
|
|
1868
|
+
| ----------------------- | -------------- | --------------------------------------- |
|
|
1869
|
+
| Internal tasks | Anonymous | No external references needed |
|
|
1870
|
+
| Event definitions | Manual | Need predictable names for listeners |
|
|
1871
|
+
| Public APIs | Manual | External modules need stable references |
|
|
1872
|
+
| Middleware | Manual | Often reused across projects |
|
|
1873
|
+
| Configuration resources | Anonymous | Usually internal infrastructure |
|
|
1874
|
+
| Test doubles/mocks | Anonymous | One-off usage in tests |
|
|
1875
|
+
| Cross-module services | Manual | Multiple files depend on them |
|
|
1876
|
+
|
|
1877
|
+
### Anonymous ID Examples by Pattern
|
|
1878
|
+
|
|
1879
|
+
```typescript
|
|
1880
|
+
// ✅ Great for anonymous IDs
|
|
1881
|
+
const database = resource({
|
|
1882
|
+
init: async () => new Database(),
|
|
1883
|
+
dispose: async (db) => db.close(),
|
|
1884
|
+
});
|
|
1885
|
+
|
|
1886
|
+
const processPayment = task({
|
|
1887
|
+
dependencies: { database },
|
|
1888
|
+
run: async (payment, { database }) => {
|
|
1889
|
+
// Internal business logic
|
|
1890
|
+
},
|
|
1891
|
+
});
|
|
1892
|
+
|
|
1893
|
+
// ✅ Better with manual IDs
|
|
1894
|
+
const paymentProcessed = event<{ paymentId: string }>({
|
|
1895
|
+
id: "app.events.paymentProcessed", // Other modules listen to this
|
|
1896
|
+
});
|
|
1897
|
+
|
|
1898
|
+
const authMiddleware = middleware({
|
|
1899
|
+
id: "app.middleware.auth", // Reused across multiple tasks
|
|
1900
|
+
run: async ({ task, next }) => {
|
|
1901
|
+
// Auth logic
|
|
1902
|
+
},
|
|
1903
|
+
});
|
|
1904
|
+
|
|
1905
|
+
// ✅ Mixed approach - totally fine!
|
|
1906
|
+
const app = resource({
|
|
1907
|
+
id: "app", // Main entry point gets manual ID
|
|
1908
|
+
register: [
|
|
1909
|
+
database, // Anonymous
|
|
1910
|
+
processPayment, // Anonymous
|
|
1911
|
+
paymentProcessed, // Manual
|
|
1912
|
+
authMiddleware, // Manual
|
|
1913
|
+
],
|
|
1914
|
+
});
|
|
1915
|
+
```
|
|
1916
|
+
|
|
1917
|
+
### Debugging with Anonymous IDs
|
|
1918
|
+
|
|
1919
|
+
Anonymous IDs show up clearly in error messages and logs:
|
|
1920
|
+
|
|
1921
|
+
```typescript
|
|
1922
|
+
// Error message example:
|
|
1923
|
+
// TaskRunError: Task failed at Symbol('tasks.payment.task')
|
|
1924
|
+
// at file:///project/src/tasks/payment.ts:15:23
|
|
1925
|
+
|
|
1926
|
+
// Logging with context:
|
|
1927
|
+
logger.info("Processing payment", {
|
|
1928
|
+
taskId: processPayment.definition.id, // Symbol('tasks.payment.task')
|
|
1929
|
+
file: "src/tasks/payment.ts",
|
|
1930
|
+
});
|
|
1931
|
+
```
|
|
1932
|
+
|
|
1673
1933
|
## Why Choose BlueLibs Runner?
|
|
1674
1934
|
|
|
1675
1935
|
### What You Get
|
package/dist/define.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ITask, ITaskDefinition, IResource, IResourceWithConfig, IResourceDefinition, IEventDefinition, IMiddlewareDefinition, DependencyMapType, DependencyValuesType, IMiddleware,
|
|
1
|
+
import { ITask, ITaskDefinition, IResource, IResourceWithConfig, IResourceDefinition, IEventDefinition, IMiddlewareDefinition, DependencyMapType, DependencyValuesType, IMiddleware, IEvent, RegisterableItems } from "./defs";
|
|
2
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 = {}, TPrivate = any>(constConfig: IResourceDefinition<TConfig, TValue, TDeps, TPrivate>): IResource<TConfig, TValue, TDeps, TPrivate>;
|
|
4
4
|
/**
|
|
@@ -10,7 +10,7 @@ export declare function defineResource<TConfig = void, TValue = any, TDeps exten
|
|
|
10
10
|
export declare function defineIndex<T extends Record<string, RegisterableItems>, D extends {
|
|
11
11
|
[K in keyof T]: T[K] extends IResourceWithConfig<any, any, any> ? T[K]["resource"] : T[K];
|
|
12
12
|
} & DependencyMapType>(items: T): IResource<void, DependencyValuesType<D>, D>;
|
|
13
|
-
export declare function defineEvent<TPayload =
|
|
13
|
+
export declare function defineEvent<TPayload = void>(config: IEventDefinition<TPayload>): IEvent<TPayload>;
|
|
14
14
|
export type MiddlewareEverywhereOptions = {
|
|
15
15
|
/**
|
|
16
16
|
* Enable this for tasks. Default is true.
|
|
@@ -25,5 +25,5 @@ export declare function defineMiddleware<TConfig extends Record<string, any>, TD
|
|
|
25
25
|
export declare function isTask(definition: any): definition is ITask;
|
|
26
26
|
export declare function isResource(definition: any): definition is IResource;
|
|
27
27
|
export declare function isResourceWithConfig(definition: any): definition is IResourceWithConfig;
|
|
28
|
-
export declare function isEvent(definition: any): definition is
|
|
28
|
+
export declare function isEvent(definition: any): definition is IEvent;
|
|
29
29
|
export declare function isMiddleware(definition: any): definition is IMiddleware;
|
package/dist/define.js
CHANGED
|
@@ -16,10 +16,12 @@ const getCallerFile_1 = require("./tools/getCallerFile");
|
|
|
16
16
|
// Helper function to get the caller file
|
|
17
17
|
function defineTask(taskConfig) {
|
|
18
18
|
const filePath = (0, getCallerFile_1.getCallerFile)();
|
|
19
|
+
const isAnonymous = !Boolean(taskConfig.id);
|
|
20
|
+
const id = taskConfig.id || (0, getCallerFile_1.generateCallerIdFromFile)(filePath, "task");
|
|
19
21
|
return {
|
|
20
22
|
[defs_1.symbols.task]: true,
|
|
21
23
|
[defs_1.symbols.filePath]: filePath,
|
|
22
|
-
id
|
|
24
|
+
id,
|
|
23
25
|
dependencies: taskConfig.dependencies || {},
|
|
24
26
|
middleware: taskConfig.middleware || [],
|
|
25
27
|
run: taskConfig.run,
|
|
@@ -28,19 +30,25 @@ function defineTask(taskConfig) {
|
|
|
28
30
|
events: {
|
|
29
31
|
beforeRun: {
|
|
30
32
|
...defineEvent({
|
|
31
|
-
id:
|
|
33
|
+
id: isAnonymous
|
|
34
|
+
? Symbol(`anonymous-task.events.beforeRun`)
|
|
35
|
+
: `${id}.events.beforeRun`,
|
|
32
36
|
}),
|
|
33
37
|
[defs_1.symbols.filePath]: (0, getCallerFile_1.getCallerFile)(),
|
|
34
38
|
},
|
|
35
39
|
afterRun: {
|
|
36
40
|
...defineEvent({
|
|
37
|
-
id:
|
|
41
|
+
id: isAnonymous
|
|
42
|
+
? Symbol(`anonymous-task.events.afterRun`)
|
|
43
|
+
: `${id}.events.afterRun`,
|
|
38
44
|
}),
|
|
39
45
|
[defs_1.symbols.filePath]: (0, getCallerFile_1.getCallerFile)(),
|
|
40
46
|
},
|
|
41
47
|
onError: {
|
|
42
48
|
...defineEvent({
|
|
43
|
-
id:
|
|
49
|
+
id: isAnonymous
|
|
50
|
+
? Symbol(`anonymous-task.events.onError`)
|
|
51
|
+
: `${id}.events.onError`,
|
|
44
52
|
}),
|
|
45
53
|
[defs_1.symbols.filePath]: (0, getCallerFile_1.getCallerFile)(),
|
|
46
54
|
},
|
|
@@ -50,11 +58,16 @@ function defineTask(taskConfig) {
|
|
|
50
58
|
};
|
|
51
59
|
}
|
|
52
60
|
function defineResource(constConfig) {
|
|
53
|
-
|
|
61
|
+
// The symbolFilePath might already come from defineIndex() for example
|
|
62
|
+
const filePath = constConfig[defs_1.symbolFilePath] || (0, getCallerFile_1.getCallerFile)();
|
|
63
|
+
const isIndexResource = constConfig[defs_1.symbolIndexResource] || false;
|
|
64
|
+
const isAnonymous = !Boolean(constConfig.id);
|
|
65
|
+
const id = constConfig.id ||
|
|
66
|
+
(0, getCallerFile_1.generateCallerIdFromFile)(filePath, isIndexResource ? "index" : "resource");
|
|
54
67
|
return {
|
|
55
68
|
[defs_1.symbols.resource]: true,
|
|
56
69
|
[defs_1.symbols.filePath]: filePath,
|
|
57
|
-
id
|
|
70
|
+
id,
|
|
58
71
|
dependencies: constConfig.dependencies,
|
|
59
72
|
dispose: constConfig.dispose,
|
|
60
73
|
register: constConfig.register || [],
|
|
@@ -72,19 +85,25 @@ function defineResource(constConfig) {
|
|
|
72
85
|
events: {
|
|
73
86
|
beforeInit: {
|
|
74
87
|
...defineEvent({
|
|
75
|
-
id:
|
|
88
|
+
id: isAnonymous
|
|
89
|
+
? Symbol(`anonymous-resource.events.beforeInit`)
|
|
90
|
+
: `${id}.events.beforeInit`,
|
|
76
91
|
}),
|
|
77
92
|
[defs_1.symbols.filePath]: filePath,
|
|
78
93
|
},
|
|
79
94
|
afterInit: {
|
|
80
95
|
...defineEvent({
|
|
81
|
-
id:
|
|
96
|
+
id: isAnonymous
|
|
97
|
+
? Symbol(`anonymous-resource.events.afterInit`)
|
|
98
|
+
: `${id}.events.afterInit`,
|
|
82
99
|
}),
|
|
83
100
|
[defs_1.symbols.filePath]: filePath,
|
|
84
101
|
},
|
|
85
102
|
onError: {
|
|
86
103
|
...defineEvent({
|
|
87
|
-
id:
|
|
104
|
+
id: isAnonymous
|
|
105
|
+
? Symbol(`anonymous-resource.events.onError`)
|
|
106
|
+
: `${id}.events.onError`,
|
|
88
107
|
}),
|
|
89
108
|
[defs_1.symbols.filePath]: filePath,
|
|
90
109
|
},
|
|
@@ -112,27 +131,33 @@ function defineIndex(items) {
|
|
|
112
131
|
dependencies[key] = item;
|
|
113
132
|
}
|
|
114
133
|
}
|
|
134
|
+
const callerFilePath = (0, getCallerFile_1.getCallerFile)();
|
|
115
135
|
return defineResource({
|
|
116
|
-
id: `index.${Math.random().toString(36).slice(2)}`,
|
|
117
136
|
register,
|
|
118
137
|
dependencies,
|
|
119
138
|
async init(_, deps) {
|
|
120
139
|
return deps;
|
|
121
140
|
},
|
|
141
|
+
[defs_1.symbols.filePath]: callerFilePath,
|
|
142
|
+
[defs_1.symbols.indexResource]: true,
|
|
122
143
|
});
|
|
123
144
|
}
|
|
124
145
|
function defineEvent(config) {
|
|
146
|
+
const callerFilePath = (0, getCallerFile_1.getCallerFile)();
|
|
125
147
|
return {
|
|
126
|
-
[defs_1.symbols.filePath]: (0, getCallerFile_1.getCallerFile)(),
|
|
127
|
-
[defs_1.symbolEvent]: true,
|
|
128
148
|
...config,
|
|
149
|
+
id: config.id || (0, getCallerFile_1.generateCallerIdFromFile)(callerFilePath, "event"),
|
|
150
|
+
[defs_1.symbols.filePath]: callerFilePath,
|
|
151
|
+
[defs_1.symbolEvent]: true, // This is a workaround
|
|
129
152
|
};
|
|
130
153
|
}
|
|
131
154
|
function defineMiddleware(middlewareDef) {
|
|
155
|
+
const filePath = (0, getCallerFile_1.getCallerFile)();
|
|
132
156
|
const object = {
|
|
133
|
-
[defs_1.symbols.filePath]:
|
|
157
|
+
[defs_1.symbols.filePath]: filePath,
|
|
134
158
|
[defs_1.symbols.middleware]: true,
|
|
135
159
|
config: {},
|
|
160
|
+
id: middlewareDef.id || (0, getCallerFile_1.generateCallerIdFromFile)(filePath, "middleware"),
|
|
136
161
|
...middlewareDef,
|
|
137
162
|
dependencies: middlewareDef.dependencies || {},
|
|
138
163
|
};
|
|
@@ -155,7 +180,7 @@ function defineMiddleware(middlewareDef) {
|
|
|
155
180
|
[defs_1.symbols.middlewareEverywhereTasks]: tasks,
|
|
156
181
|
[defs_1.symbols.middlewareEverywhereResources]: resources,
|
|
157
182
|
everywhere() {
|
|
158
|
-
throw errors_1.Errors.middlewareAlreadyGlobal(
|
|
183
|
+
throw errors_1.Errors.middlewareAlreadyGlobal(object.id);
|
|
159
184
|
},
|
|
160
185
|
};
|
|
161
186
|
},
|
package/dist/define.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"define.js","sourceRoot":"","sources":["../src/define.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"define.js","sourceRoot":"","sources":["../src/define.ts"],"names":[],"mappings":"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"}
|