@gesslar/actioneer 2.2.0 → 2.4.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/package.json +16 -17
- package/src/browser/lib/ActionBuilder.js +87 -65
- package/src/browser/lib/ActionHooks.js +35 -27
- package/src/browser/lib/ActionRunner.js +85 -40
- package/src/browser/lib/ActionWrapper.js +13 -6
- package/src/browser/lib/Activity.js +17 -13
- package/src/browser/lib/Piper.js +46 -22
- package/src/types/browser/lib/ActionBuilder.d.ts +80 -58
- package/src/types/browser/lib/ActionBuilder.d.ts.map +1 -1
- package/src/types/browser/lib/ActionHooks.d.ts +28 -26
- package/src/types/browser/lib/ActionHooks.d.ts.map +1 -1
- package/src/types/browser/lib/ActionRunner.d.ts +7 -5
- package/src/types/browser/lib/ActionRunner.d.ts.map +1 -1
- package/src/types/browser/lib/ActionWrapper.d.ts +14 -5
- package/src/types/browser/lib/ActionWrapper.d.ts.map +1 -1
- package/src/types/browser/lib/Activity.d.ts +20 -14
- package/src/types/browser/lib/Activity.d.ts.map +1 -1
- package/src/types/browser/lib/Piper.d.ts +14 -9
- package/src/types/browser/lib/Piper.d.ts.map +1 -1
package/package.json
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
"name": "gesslar",
|
|
6
6
|
"url": "https://gesslar.dev"
|
|
7
7
|
},
|
|
8
|
-
"version": "2.
|
|
8
|
+
"version": "2.4.0",
|
|
9
9
|
"license": "Unlicense",
|
|
10
10
|
"homepage": "https://github.com/gesslar/toolkit#readme",
|
|
11
11
|
"repository": {
|
|
@@ -22,7 +22,6 @@
|
|
|
22
22
|
"composition",
|
|
23
23
|
"lasagna"
|
|
24
24
|
],
|
|
25
|
-
"main": "./src/index.js",
|
|
26
25
|
"type": "module",
|
|
27
26
|
"exports": {
|
|
28
27
|
".": {
|
|
@@ -46,28 +45,28 @@
|
|
|
46
45
|
],
|
|
47
46
|
"sideEffects": false,
|
|
48
47
|
"engines": {
|
|
49
|
-
"node": ">=
|
|
50
|
-
},
|
|
51
|
-
"dependencies": {
|
|
52
|
-
"@gesslar/toolkit": "^3.24.0"
|
|
53
|
-
},
|
|
54
|
-
"devDependencies": {
|
|
55
|
-
"@gesslar/uglier": "^1.2.0",
|
|
56
|
-
"eslint": "^9.39.2",
|
|
57
|
-
"typescript": "^5.9.3"
|
|
48
|
+
"node": ">=24.13.0"
|
|
58
49
|
},
|
|
59
50
|
"scripts": {
|
|
60
51
|
"lint": "eslint src/",
|
|
61
52
|
"lint:fix": "eslint src/ --fix",
|
|
62
53
|
"types": "node -e \"require('fs').rmSync('types',{recursive:true,force:true});\" && tsc -p tsconfig.types.json",
|
|
63
|
-
"submit": "
|
|
64
|
-
"update": "
|
|
54
|
+
"submit": "npm publish --access public --//registry.npmjs.org/:_authToken=\"${NPM_ACCESS_TOKEN}\"",
|
|
55
|
+
"update": "npx npm-check-updates -u && npm install",
|
|
65
56
|
"test": "node --test tests/**/*.test.js",
|
|
66
57
|
"test:browser": "node --test tests/browser/*.test.js",
|
|
67
58
|
"test:node": "node --test tests/node/*.test.js",
|
|
68
59
|
"pr": "gt submit -p --ai",
|
|
69
|
-
"patch": "
|
|
70
|
-
"minor": "
|
|
71
|
-
"major": "
|
|
60
|
+
"patch": "npm version patch",
|
|
61
|
+
"minor": "npm version minor",
|
|
62
|
+
"major": "npm version major"
|
|
63
|
+
},
|
|
64
|
+
"dependencies": {
|
|
65
|
+
"@gesslar/toolkit": "^3.37.0"
|
|
66
|
+
},
|
|
67
|
+
"devDependencies": {
|
|
68
|
+
"@gesslar/uglier": "^1.6.2",
|
|
69
|
+
"eslint": "^10.0.0",
|
|
70
|
+
"typescript": "^5.9.3"
|
|
72
71
|
}
|
|
73
|
-
}
|
|
72
|
+
}
|
|
@@ -4,36 +4,29 @@ import ActionWrapper from "./ActionWrapper.js"
|
|
|
4
4
|
import ActionHooks from "./ActionHooks.js"
|
|
5
5
|
import {ACTIVITY} from "./Activity.js"
|
|
6
6
|
|
|
7
|
-
/** @typedef {import("./ActionRunner.js").default} ActionRunner */
|
|
8
|
-
/** @typedef {typeof import("./Activity.js").ACTIVITY} ActivityFlags */
|
|
9
|
-
|
|
10
7
|
/**
|
|
8
|
+
* Type imports and definitions.
|
|
9
|
+
*
|
|
10
|
+
* @import {default as ActionRunner} from "./ActionRunner.js"
|
|
11
|
+
*
|
|
11
12
|
* @typedef {(message: string, level?: number, ...args: Array<unknown>) => void} DebugFn
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
/**
|
|
13
|
+
*
|
|
15
14
|
* @typedef {object} ActionBuilderAction
|
|
16
|
-
* @property {(builder: ActionBuilder) => void} setup Function invoked during {@link ActionBuilder
|
|
17
|
-
* @property {symbol} [tag] Optional tag to reuse when reconstructing builders.
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
/**
|
|
15
|
+
* @property {(builder: ActionBuilder) => void} setup - Function invoked during {@link ActionBuilder} to register activities.
|
|
16
|
+
* @property {symbol} [tag] - Optional tag to reuse when reconstructing builders.
|
|
17
|
+
*
|
|
21
18
|
* @typedef {object} ActionBuilderConfig
|
|
22
|
-
* @property {symbol} [tag] Optional tag for the builder instance.
|
|
23
|
-
* @property {DebugFn} [debug] Logger used by the pipeline internals.
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
/**
|
|
19
|
+
* @property {symbol} [tag] - Optional tag for the builder instance.
|
|
20
|
+
* @property {DebugFn} [debug] - Logger used by the pipeline internals.
|
|
21
|
+
*
|
|
27
22
|
* @typedef {object} ActivityDefinition
|
|
28
|
-
* @property {ActionBuilderAction|null} action Parent action instance when available.
|
|
29
|
-
* @property {DebugFn|null} debug Logger function.
|
|
30
|
-
* @property {string|symbol} name Activity identifier.
|
|
31
|
-
* @property {ActionFunction|import("./ActionWrapper.js").default} op Operation to execute.
|
|
32
|
-
* @property {number} [kind] Optional kind flags from {@link
|
|
33
|
-
* @property {(context: unknown) => boolean|Promise<boolean>} [pred] Loop predicate.
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
/**
|
|
23
|
+
* @property {ActionBuilderAction|null} action - Parent action instance when available.
|
|
24
|
+
* @property {DebugFn|null} debug - Logger function.
|
|
25
|
+
* @property {string|symbol} name - Activity identifier.
|
|
26
|
+
* @property {ActionFunction|import("./ActionWrapper.js").default} op - Operation to execute.
|
|
27
|
+
* @property {number} [kind] - Optional kind flags from {@link ACTIVITY}.
|
|
28
|
+
* @property {(context: unknown) => boolean|Promise<boolean>} [pred] - Loop predicate.
|
|
29
|
+
*
|
|
37
30
|
* @typedef {(context: unknown) => unknown|Promise<unknown>} ActionFunction
|
|
38
31
|
*/
|
|
39
32
|
|
|
@@ -58,28 +51,28 @@ import {ACTIVITY} from "./Activity.js"
|
|
|
58
51
|
* @class ActionBuilder
|
|
59
52
|
*/
|
|
60
53
|
export default class ActionBuilder {
|
|
61
|
-
/** @type {ActionBuilderAction
|
|
54
|
+
/** @type {ActionBuilderAction?} */
|
|
62
55
|
#action = null
|
|
63
56
|
/** @type {Map<string|symbol, ActivityDefinition>} */
|
|
64
57
|
#activities = new Map([])
|
|
65
|
-
/** @type {DebugFn
|
|
58
|
+
/** @type {DebugFn?} */
|
|
66
59
|
#debug = null
|
|
67
|
-
/** @type {symbol
|
|
60
|
+
/** @type {symbol?} */
|
|
68
61
|
#tag = null
|
|
69
|
-
/** @type {string
|
|
62
|
+
/** @type {string?} */
|
|
70
63
|
#hooksFile = null
|
|
71
|
-
/** @type {string
|
|
64
|
+
/** @type {string?} */
|
|
72
65
|
#hooksKind = null
|
|
73
|
-
/** @type {
|
|
66
|
+
/** @type {ActionHooks?} */
|
|
74
67
|
#hooks = null
|
|
75
|
-
/** @type {ActionFunction
|
|
68
|
+
/** @type {ActionFunction?} */
|
|
76
69
|
#done = null
|
|
77
70
|
|
|
78
71
|
/**
|
|
79
72
|
* Creates a new ActionBuilder instance with the provided action callback.
|
|
80
73
|
*
|
|
81
|
-
* @param {ActionBuilderAction} [action] Base action invoked by the runner when a block satisfies the configured structure.
|
|
82
|
-
* @param {ActionBuilderConfig} [config] Options
|
|
74
|
+
* @param {ActionBuilderAction} [action] - Base action invoked by the runner when a block satisfies the configured structure.
|
|
75
|
+
* @param {ActionBuilderConfig} [config] - Options
|
|
83
76
|
*/
|
|
84
77
|
constructor(
|
|
85
78
|
action,
|
|
@@ -89,6 +82,9 @@ export default class ActionBuilder {
|
|
|
89
82
|
this.#tag = this.#tag || tag
|
|
90
83
|
|
|
91
84
|
if(action) {
|
|
85
|
+
if(action.tag)
|
|
86
|
+
throw Sass.new("Action has already been consumed by a builder and cannot be reused.")
|
|
87
|
+
|
|
92
88
|
if(Data.typeOf(action.setup) !== "Function")
|
|
93
89
|
throw Sass.new("Setup must be a function.")
|
|
94
90
|
|
|
@@ -110,44 +106,44 @@ export default class ActionBuilder {
|
|
|
110
106
|
* - do(name, kind, splitter, rejoiner, opOrWrapper) - SPLIT with parallel execution
|
|
111
107
|
*
|
|
112
108
|
* @overload
|
|
113
|
-
* @param {string|symbol} name Activity name
|
|
114
|
-
* @param {ActionFunction} op Operation to execute once.
|
|
109
|
+
* @param {string|symbol} name - Activity name
|
|
110
|
+
* @param {ActionFunction} op - Operation to execute once.
|
|
115
111
|
* @returns {ActionBuilder}
|
|
116
112
|
*/
|
|
117
113
|
|
|
118
114
|
/**
|
|
119
115
|
* @overload
|
|
120
|
-
* @param {string|symbol} name Activity name
|
|
121
|
-
* @param {number} kind ACTIVITY.BREAK or ACTIVITY.CONTINUE flag.
|
|
122
|
-
* @param {(context: unknown) => boolean|Promise<boolean>} pred Predicate to evaluate for control flow.
|
|
116
|
+
* @param {string|symbol} name - Activity name
|
|
117
|
+
* @param {number} kind - ACTIVITY.BREAK or ACTIVITY.CONTINUE flag.
|
|
118
|
+
* @param {(context: unknown) => boolean|Promise<boolean>} pred - Predicate to evaluate for control flow.
|
|
123
119
|
* @returns {ActionBuilder}
|
|
124
120
|
*/
|
|
125
121
|
|
|
126
122
|
/**
|
|
127
123
|
* @overload
|
|
128
|
-
* @param {string|symbol} name Activity name
|
|
129
|
-
* @param {number} kind Activity kind (WHILE, UNTIL, or IF) from {@link
|
|
130
|
-
* @param {(context: unknown) => boolean|Promise<boolean>} pred Predicate executed before/after the op.
|
|
131
|
-
* @param {ActionFunction|ActionBuilder} op Operation or nested builder to execute.
|
|
124
|
+
* @param {string|symbol} name - Activity name
|
|
125
|
+
* @param {number} kind - Activity kind (WHILE, UNTIL, or IF) from {@link ACTIVITY}.
|
|
126
|
+
* @param {(context: unknown) => boolean|Promise<boolean>} pred - Predicate executed before/after the op.
|
|
127
|
+
* @param {ActionFunction|ActionBuilder} op - Operation or nested builder to execute.
|
|
132
128
|
* @returns {ActionBuilder}
|
|
133
129
|
*/
|
|
134
130
|
|
|
135
131
|
/**
|
|
136
132
|
* @overload
|
|
137
|
-
* @param {string|symbol} name Activity name
|
|
138
|
-
* @param {number} kind ACTIVITY.SPLIT flag.
|
|
139
|
-
* @param {(context: unknown) => unknown} splitter Splitter function for SPLIT mode.
|
|
140
|
-
* @param {(originalContext: unknown, splitResults: unknown) => unknown} rejoiner Rejoiner function for SPLIT mode.
|
|
141
|
-
* @param {ActionFunction|ActionBuilder} op Operation or nested builder to execute.
|
|
133
|
+
* @param {string|symbol} name - Activity name
|
|
134
|
+
* @param {number} kind - ACTIVITY.SPLIT flag.
|
|
135
|
+
* @param {(context: unknown) => unknown} splitter - Splitter function for SPLIT mode.
|
|
136
|
+
* @param {(originalContext: unknown, splitResults: unknown) => unknown} rejoiner - Rejoiner function for SPLIT mode.
|
|
137
|
+
* @param {ActionFunction|ActionBuilder} op - Operation or nested builder to execute.
|
|
142
138
|
* @returns {ActionBuilder}
|
|
143
139
|
*/
|
|
144
140
|
|
|
145
141
|
/**
|
|
146
142
|
* Handles runtime dispatch across the documented overloads.
|
|
147
143
|
*
|
|
148
|
-
* @param {string|symbol} name Activity name
|
|
149
|
-
* @param {...unknown} args See overloads
|
|
150
|
-
* @returns {ActionBuilder} The builder instance for chaining
|
|
144
|
+
* @param {string|symbol} name - Activity name
|
|
145
|
+
* @param {...unknown} args - See overloads
|
|
146
|
+
* @returns {ActionBuilder} - The builder instance for chaining
|
|
151
147
|
*/
|
|
152
148
|
do(name, ...args) {
|
|
153
149
|
this.#dupeActivityCheck(name)
|
|
@@ -209,9 +205,9 @@ export default class ActionBuilder {
|
|
|
209
205
|
/**
|
|
210
206
|
* Configure hooks to be loaded from a file when the action is built.
|
|
211
207
|
*
|
|
212
|
-
* @param {string} hooksFile Path to the hooks module file.
|
|
213
|
-
* @param {string} hooksKind Name of the exported hooks class to instantiate.
|
|
214
|
-
* @returns {ActionBuilder} The builder instance for chaining.
|
|
208
|
+
* @param {string} hooksFile - Path to the hooks module file.
|
|
209
|
+
* @param {string} hooksKind - Name of the exported hooks class to instantiate.
|
|
210
|
+
* @returns {ActionBuilder} - The builder instance for chaining.
|
|
215
211
|
* @throws {Sass} If hooks have already been configured.
|
|
216
212
|
*/
|
|
217
213
|
withHooksFile(hooksFile, hooksKind) {
|
|
@@ -228,15 +224,15 @@ export default class ActionBuilder {
|
|
|
228
224
|
/**
|
|
229
225
|
* Configure hooks using a pre-instantiated hooks object.
|
|
230
226
|
*
|
|
231
|
-
* @param {
|
|
232
|
-
* @returns {ActionBuilder} The builder instance for chaining.
|
|
227
|
+
* @param {ActionHooks} hooks - An already-instantiated hooks instance.
|
|
228
|
+
* @returns {ActionBuilder} - The builder instance for chaining.
|
|
233
229
|
* @throws {Sass} If hooks have already been configured with a different instance.
|
|
234
230
|
*/
|
|
235
231
|
withHooks(hooks) {
|
|
236
|
-
// If the same hooks instance is already set, this is idempotent -
|
|
237
|
-
|
|
232
|
+
// If the same hooks instance is already set, this is idempotent -just
|
|
233
|
+
// return.
|
|
234
|
+
if(this.#hooks === hooks)
|
|
238
235
|
return this
|
|
239
|
-
}
|
|
240
236
|
|
|
241
237
|
Valid.assert(this.#hooksFile === null, "Hooks have already been configured.")
|
|
242
238
|
Valid.assert(this.#hooksKind === null, "Hooks have already been configured.")
|
|
@@ -251,7 +247,7 @@ export default class ActionBuilder {
|
|
|
251
247
|
* Configure the action instance if not already set.
|
|
252
248
|
* Used to propagate parent action context to nested builders.
|
|
253
249
|
*
|
|
254
|
-
* @param {ActionBuilderAction} action The action instance to inherit.
|
|
250
|
+
* @param {ActionBuilderAction} action - The action instance to inherit.
|
|
255
251
|
* @returns {ActionBuilder} The builder instance for chaining.
|
|
256
252
|
*/
|
|
257
253
|
withAction(action) {
|
|
@@ -271,7 +267,7 @@ export default class ActionBuilder {
|
|
|
271
267
|
/**
|
|
272
268
|
* Register a callback to be executed after all activities complete.
|
|
273
269
|
*
|
|
274
|
-
* @param {ActionFunction} callback Function to execute at the end of the pipeline.
|
|
270
|
+
* @param {ActionFunction} callback - Function to execute at the end of the pipeline.
|
|
275
271
|
* @returns {ActionBuilder} The builder instance for chaining.
|
|
276
272
|
*/
|
|
277
273
|
done(callback) {
|
|
@@ -285,7 +281,7 @@ export default class ActionBuilder {
|
|
|
285
281
|
* Validates that an activity name has not been reused.
|
|
286
282
|
*
|
|
287
283
|
* @private
|
|
288
|
-
* @param {string
|
|
284
|
+
* @param {string|symbol} name Activity identifier.
|
|
289
285
|
*/
|
|
290
286
|
#dupeActivityCheck(name) {
|
|
291
287
|
Valid.assert(
|
|
@@ -298,9 +294,10 @@ export default class ActionBuilder {
|
|
|
298
294
|
* Finalises the builder and returns a payload that can be consumed by the
|
|
299
295
|
* runner.
|
|
300
296
|
*
|
|
301
|
-
* @
|
|
297
|
+
* @param {ActionRunner} runner - The runner invoking the build.
|
|
298
|
+
* @returns {Promise<ActionWrapper>} Payload consumed by the {@link ActionRunner} constructor.
|
|
302
299
|
*/
|
|
303
|
-
async build() {
|
|
300
|
+
async build(runner) {
|
|
304
301
|
const action = this.#action
|
|
305
302
|
|
|
306
303
|
if(action && !action.tag) {
|
|
@@ -309,6 +306,20 @@ export default class ActionBuilder {
|
|
|
309
306
|
await Promise.resolve(action.setup.call(action, this))
|
|
310
307
|
}
|
|
311
308
|
|
|
309
|
+
if(action) {
|
|
310
|
+
// Inject a method to the action for emission, but only if it's undefined.
|
|
311
|
+
if(Data.isType(action.emit, "Undefined"))
|
|
312
|
+
action.emit = (...args) => runner.emit(...args)
|
|
313
|
+
|
|
314
|
+
// Inject a method to the action for onission, but only if it's undefined.
|
|
315
|
+
if(Data.isType(action.on, "Undefined"))
|
|
316
|
+
action.on = (event, cb) => runner.on(event, cb)
|
|
317
|
+
|
|
318
|
+
// Inject a method to the action for offission, but only if it's undefined.
|
|
319
|
+
if(Data.isType(action.off, "Undefined"))
|
|
320
|
+
action.off = (event, cb) => runner.off(event, cb)
|
|
321
|
+
}
|
|
322
|
+
|
|
312
323
|
// All children in a branch also get the same hooks.
|
|
313
324
|
const hooks = await this.#getHooks()
|
|
314
325
|
|
|
@@ -317,7 +328,8 @@ export default class ActionBuilder {
|
|
|
317
328
|
debug: this.#debug,
|
|
318
329
|
hooks,
|
|
319
330
|
done: this.#done,
|
|
320
|
-
action
|
|
331
|
+
action,
|
|
332
|
+
runner: runner,
|
|
321
333
|
})
|
|
322
334
|
}
|
|
323
335
|
|
|
@@ -340,4 +352,14 @@ export default class ActionBuilder {
|
|
|
340
352
|
if(hooksFile && hooksKind)
|
|
341
353
|
return await newHooks({hooksFile,hooksKind}, this.#debug)
|
|
342
354
|
}
|
|
355
|
+
|
|
356
|
+
/**
|
|
357
|
+
* Returns the raw hooks value configured on this builder.
|
|
358
|
+
* Used by {@link ActionRunner} to access setup/cleanup lifecycle hooks.
|
|
359
|
+
*
|
|
360
|
+
* @returns {object|Function|null} Raw hooks value, or null if not configured.
|
|
361
|
+
*/
|
|
362
|
+
get hooks() {
|
|
363
|
+
return this.#hooks
|
|
364
|
+
}
|
|
343
365
|
}
|
|
@@ -4,16 +4,14 @@ import {Data, Sass, Promised, Time, Util, Valid} from "@gesslar/toolkit"
|
|
|
4
4
|
* @typedef {(message: string, level?: number, ...args: Array<unknown>) => void} DebugFn
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
/**
|
|
8
|
-
* @typedef {object} ActionHooksConfig
|
|
9
|
-
* @property {string} actionKind Action identifier shared between runner and hooks.
|
|
10
|
-
* @property {unknown} hooks Already-instantiated hooks implementation.
|
|
11
|
-
* @property {number} [hookTimeout] Timeout applied to hook execution in milliseconds.
|
|
12
|
-
* @property {DebugFn} debug Logger to emit diagnostics.
|
|
13
|
-
*/
|
|
14
|
-
|
|
15
7
|
/**
|
|
16
8
|
* @typedef {Record<string, (context: unknown) => Promise<unknown>|unknown>} HookModule
|
|
9
|
+
*
|
|
10
|
+
* @typedef {object} ActionHooksConfig
|
|
11
|
+
* @property {string} actionKind - Action identifier shared between runner and hooks.
|
|
12
|
+
* @property {object|Function|null} hooks - Pre-instantiated hooks object, a constructor to instantiate, or null.
|
|
13
|
+
* @property {number} [hookTimeout] - Timeout applied to hook execution in milliseconds.
|
|
14
|
+
* @property {DebugFn} debug - Logger to emit diagnostics.
|
|
17
15
|
*/
|
|
18
16
|
|
|
19
17
|
/**
|
|
@@ -24,19 +22,19 @@ import {Data, Sass, Promised, Time, Util, Valid} from "@gesslar/toolkit"
|
|
|
24
22
|
* Browser version: Requires pre-instantiated hooks. File-based loading is not supported.
|
|
25
23
|
*/
|
|
26
24
|
export default class ActionHooks {
|
|
27
|
-
/** @type {HookModule
|
|
25
|
+
/** @type {HookModule?} */
|
|
28
26
|
#hooks = null
|
|
29
|
-
/** @type {string
|
|
27
|
+
/** @type {string?} */
|
|
30
28
|
#actionKind = null
|
|
31
29
|
/** @type {number} */
|
|
32
30
|
#timeout = 1_000 // Default 1 second timeout
|
|
33
|
-
/** @type {DebugFn
|
|
31
|
+
/** @type {DebugFn?} */
|
|
34
32
|
#debug = null
|
|
35
33
|
|
|
36
34
|
/**
|
|
37
35
|
* Creates a new ActionHook instance.
|
|
38
36
|
*
|
|
39
|
-
* @param {ActionHooksConfig} config Configuration values describing how to load the hooks.
|
|
37
|
+
* @param {ActionHooksConfig} config - Configuration values describing how to load the hooks.
|
|
40
38
|
*/
|
|
41
39
|
constructor({actionKind, hooks, hookTimeout = 1_000, debug}) {
|
|
42
40
|
this.#actionKind = actionKind
|
|
@@ -56,10 +54,18 @@ export default class ActionHooks {
|
|
|
56
54
|
|
|
57
55
|
/**
|
|
58
56
|
* Gets the loaded hooks object.
|
|
57
|
+
* If the stored value is a plain object it is returned as-is.
|
|
58
|
+
* If it is a constructor function a new instance is created and returned.
|
|
59
59
|
*
|
|
60
|
-
* @returns {object
|
|
60
|
+
* @returns {object?} Hooks object or null if not loaded
|
|
61
61
|
*/
|
|
62
62
|
get hooks() {
|
|
63
|
+
if(Data.isType(this.#hooks, "Object"))
|
|
64
|
+
return this.#hooks
|
|
65
|
+
|
|
66
|
+
else if(Data.isType(this.#hooks, "Function"))
|
|
67
|
+
return new this.#hooks()
|
|
68
|
+
|
|
63
69
|
return this.#hooks
|
|
64
70
|
}
|
|
65
71
|
|
|
@@ -75,7 +81,7 @@ export default class ActionHooks {
|
|
|
75
81
|
/**
|
|
76
82
|
* Gets the setup hook function if available.
|
|
77
83
|
*
|
|
78
|
-
* @returns {(args: object) => unknown
|
|
84
|
+
* @returns {(args: object) => unknown} Setup hook function or null
|
|
79
85
|
*/
|
|
80
86
|
get setup() {
|
|
81
87
|
return this.hooks?.setup || null
|
|
@@ -84,7 +90,7 @@ export default class ActionHooks {
|
|
|
84
90
|
/**
|
|
85
91
|
* Gets the cleanup hook function if available.
|
|
86
92
|
*
|
|
87
|
-
* @returns {(args: object) => unknown
|
|
93
|
+
* @returns {(args: object) => unknown} Cleanup hook function or null
|
|
88
94
|
*/
|
|
89
95
|
get cleanup() {
|
|
90
96
|
return this.hooks?.cleanup || null
|
|
@@ -94,12 +100,12 @@ export default class ActionHooks {
|
|
|
94
100
|
* Static factory method to create and initialize a hook manager.
|
|
95
101
|
* Browser version: Only works with pre-instantiated hooks passed via config.hooks.
|
|
96
102
|
*
|
|
97
|
-
* @param {ActionHooksConfig} config Configuration object with hooks property
|
|
98
|
-
* @param {DebugFn} debug The debug function.
|
|
99
|
-
* @returns {Promise<ActionHooks
|
|
103
|
+
* @param {ActionHooksConfig} config - Configuration object with hooks property
|
|
104
|
+
* @param {DebugFn} debug - The debug function.
|
|
105
|
+
* @returns {Promise<ActionHooks?>} Initialized hook manager or null if no hooks provided
|
|
100
106
|
*/
|
|
101
107
|
static async new(config, debug) {
|
|
102
|
-
debug("Creating new
|
|
108
|
+
debug("Creating new ActionHooks instance with args: %o", 2, config)
|
|
103
109
|
|
|
104
110
|
if(!config.hooks) {
|
|
105
111
|
debug("No hooks provided (browser mode requires pre-instantiated hooks)", 2)
|
|
@@ -117,12 +123,13 @@ export default class ActionHooks {
|
|
|
117
123
|
/**
|
|
118
124
|
* Invoke a dynamically-named hook such as `before$foo`.
|
|
119
125
|
*
|
|
120
|
-
* @param {
|
|
121
|
-
* @param {string|symbol} activityName Activity identifier.
|
|
122
|
-
* @param {unknown}
|
|
126
|
+
* @param {string} kind - Hook namespace.
|
|
127
|
+
* @param {string|symbol} activityName - Activity identifier.
|
|
128
|
+
* @param {unknown} oldContext - Pipeline context supplied to the hook.
|
|
129
|
+
* @param {unknown} newContext - For after$ hooks, the result of the op
|
|
123
130
|
* @returns {Promise<void>}
|
|
124
131
|
*/
|
|
125
|
-
async callHook(kind, activityName,
|
|
132
|
+
async callHook(kind, activityName, oldContext, newContext) {
|
|
126
133
|
try {
|
|
127
134
|
const debug = this.#debug
|
|
128
135
|
const hooks = this.#hooks
|
|
@@ -149,7 +156,11 @@ export default class ActionHooks {
|
|
|
149
156
|
debug("Hook function starting execution: %o", 4, hookName)
|
|
150
157
|
|
|
151
158
|
const duration = (
|
|
152
|
-
|
|
159
|
+
newContext
|
|
160
|
+
? await Util.time(
|
|
161
|
+
() => hook.call(this.#hooks, newContext, oldContext)
|
|
162
|
+
)
|
|
163
|
+
: await Util.time(() => hook.call(this.#hooks, oldContext))
|
|
153
164
|
).cost
|
|
154
165
|
|
|
155
166
|
debug("Hook function completed successfully: %o, after %oms", 4, hookName, duration)
|
|
@@ -170,9 +181,6 @@ export default class ActionHooks {
|
|
|
170
181
|
} catch(error) {
|
|
171
182
|
throw Sass.new(`Processing hook ${kind}$${activityName}`, error)
|
|
172
183
|
}
|
|
173
|
-
|
|
174
|
-
debug("We made it throoough the wildernessss", 4)
|
|
175
|
-
|
|
176
184
|
} catch(error) {
|
|
177
185
|
throw Sass.new(`Processing hook ${kind}$${activityName}`, error)
|
|
178
186
|
}
|