@gesslar/toolkit 0.5.0 → 0.7.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 +8 -8
- package/src/lib/Collection.js +132 -17
- package/src/lib/Contract.js +1 -1
- package/src/lib/Data.js +27 -18
- package/src/lib/DirectoryObject.js +1 -1
- package/src/lib/FS.js +10 -0
- package/src/lib/Glog.js +27 -10
- package/src/lib/Logger.js +3 -0
- package/src/lib/Sass.js +6 -1
- package/src/lib/Tantrum.js +43 -0
- package/src/lib/TypeSpec.js +11 -7
- package/src/lib/Util.js +82 -0
- package/src/lib/Valid.js +24 -6
- package/src/types/Collection.d.ts +6 -1
- package/src/types/Contract.d.ts +27 -27
- package/src/types/Data.d.ts +23 -23
- package/src/types/FS.d.ts +3 -3
- package/src/types/Glog.d.ts +302 -49
- package/src/types/Sass.d.ts +1 -1
- package/src/types/Schemer.d.ts +29 -29
- package/src/types/Tantrum.d.ts +10 -10
- package/src/types/Term.d.ts +1 -1
- package/src/types/Terms.d.ts +21 -21
- package/src/types/Type.d.ts +1 -1
- package/src/types/Util.d.ts +20 -2
- package/src/types/index.d.ts +17 -23
- package/src/types/index.d.ts.map +1 -0
- package/src/types/lib/Cache.d.ts +28 -0
- package/src/types/lib/Cache.d.ts.map +1 -0
- package/src/types/lib/Collection.d.ts +246 -0
- package/src/types/lib/Collection.d.ts.map +1 -0
- package/src/types/lib/Contract.d.ts +72 -0
- package/src/types/lib/Contract.d.ts.map +1 -0
- package/src/types/lib/Data.d.ts +189 -0
- package/src/types/lib/Data.d.ts.map +1 -0
- package/src/types/lib/DirectoryObject.d.ts +148 -0
- package/src/types/lib/DirectoryObject.d.ts.map +1 -0
- package/src/types/lib/FS.d.ts +70 -0
- package/src/types/lib/FS.d.ts.map +1 -0
- package/src/types/lib/FileObject.d.ts +189 -0
- package/src/types/lib/FileObject.d.ts.map +1 -0
- package/src/types/lib/Glog.d.ts +113 -0
- package/src/types/lib/Glog.d.ts.map +1 -0
- package/src/types/lib/Logger.d.ts +46 -0
- package/src/types/lib/Logger.d.ts.map +1 -0
- package/src/types/lib/Sass.d.ts +62 -0
- package/src/types/lib/Sass.d.ts.map +1 -0
- package/src/types/lib/Schemer.d.ts +23 -0
- package/src/types/lib/Schemer.d.ts.map +1 -0
- package/src/types/lib/Tantrum.d.ts +50 -0
- package/src/types/lib/Tantrum.d.ts.map +1 -0
- package/src/types/lib/Term.d.ts +103 -0
- package/src/types/lib/Term.d.ts.map +1 -0
- package/src/types/lib/Terms.d.ts +24 -0
- package/src/types/lib/Terms.d.ts.map +1 -0
- package/src/types/lib/TypeSpec.d.ts +92 -0
- package/src/types/lib/TypeSpec.d.ts.map +1 -0
- package/src/types/lib/Util.d.ts +197 -0
- package/src/types/lib/Util.d.ts.map +1 -0
- package/src/types/lib/Valid.d.ts +33 -0
- package/src/types/lib/Valid.d.ts.map +1 -0
- package/src/lib/Action.js +0 -283
- package/src/lib/ActionBuilder.js +0 -144
- package/src/lib/ActionRunner.js +0 -79
- package/src/lib/Hooks.js +0 -194
- package/src/lib/Piper.js +0 -155
package/src/lib/ActionRunner.js
DELETED
|
@@ -1,79 +0,0 @@
|
|
|
1
|
-
import ActionBuilder, {ACTIVITY} from "./ActionBuilder.js"
|
|
2
|
-
import Piper from "./Piper.js"
|
|
3
|
-
import Sass from "./Sass.js"
|
|
4
|
-
/**
|
|
5
|
-
* Orchestrates execution of {@link ActionBuilder}-produced pipelines.
|
|
6
|
-
*
|
|
7
|
-
* Activities run in insertion order, with support for once-off work, repeated
|
|
8
|
-
* loops, and nested parallel pipelines. Each activity receives a mutable
|
|
9
|
-
* context object under `result.value` that can be replaced or enriched.
|
|
10
|
-
*/
|
|
11
|
-
export default class ActionRunner {
|
|
12
|
-
#action = null
|
|
13
|
-
#build = null
|
|
14
|
-
#hooks = null
|
|
15
|
-
|
|
16
|
-
constructor({action, build}, hooks) {
|
|
17
|
-
this.#action = action
|
|
18
|
-
this.#build = build
|
|
19
|
-
this.#hooks = hooks
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* Executes the configured action pipeline.
|
|
24
|
-
*
|
|
25
|
-
* @param {unknown} content Seed value passed to the first activity.
|
|
26
|
-
* @returns {Promise<unknown>} Final value produced by the pipeline, or null when a parallel stage reports failures.
|
|
27
|
-
* @throws {Sass} When no activities are registered or required parallel builders are missing.
|
|
28
|
-
*/
|
|
29
|
-
async run(content) {
|
|
30
|
-
const activities = this.#build.activities
|
|
31
|
-
|
|
32
|
-
if(!activities.size)
|
|
33
|
-
throw Sass.new("No activities defined in action.")
|
|
34
|
-
|
|
35
|
-
const result = content
|
|
36
|
-
const action = this.#action
|
|
37
|
-
|
|
38
|
-
for(const [name,activity] of activities) {
|
|
39
|
-
const {op} = activity
|
|
40
|
-
|
|
41
|
-
if(activity.kind === ACTIVITY.ONCE) {
|
|
42
|
-
this.#hooks && await this.#hooks.callHook("before", name, result)
|
|
43
|
-
|
|
44
|
-
if(!await op.call(action, result))
|
|
45
|
-
break
|
|
46
|
-
|
|
47
|
-
this.#hooks && await this.#hooks.callHook("after", name, result)
|
|
48
|
-
} else if(activity.kind == ACTIVITY.MANY) {
|
|
49
|
-
for(;;) {
|
|
50
|
-
|
|
51
|
-
this.#hooks && await this.#hooks.callHook("before", name, result)
|
|
52
|
-
|
|
53
|
-
if(!await op.call(action, result))
|
|
54
|
-
break
|
|
55
|
-
|
|
56
|
-
this.#hooks && await this.#hooks.callHook("after", name, result)
|
|
57
|
-
}
|
|
58
|
-
} else if(activity.kind === ACTIVITY.PARALLEL) {
|
|
59
|
-
if(op === undefined)
|
|
60
|
-
throw Sass.new("Missing action builder. Did you return the builder?")
|
|
61
|
-
|
|
62
|
-
if(!op)
|
|
63
|
-
throw Sass.new("Okay, cheeky monkey, you need to return the builder for this to work.")
|
|
64
|
-
|
|
65
|
-
const builder = op.build()
|
|
66
|
-
const piper = new Piper()
|
|
67
|
-
.addStep(item => {
|
|
68
|
-
const runner = new ActionRunner(builder, this.#hooks)
|
|
69
|
-
|
|
70
|
-
return runner.run(item)
|
|
71
|
-
}, {name: `Process Parallel ActionRunner Activity`,})
|
|
72
|
-
|
|
73
|
-
await piper.pipe(result.value)
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
return result
|
|
78
|
-
}
|
|
79
|
-
}
|
package/src/lib/Hooks.js
DELETED
|
@@ -1,194 +0,0 @@
|
|
|
1
|
-
import {setTimeout as timeout} from "timers/promises"
|
|
2
|
-
|
|
3
|
-
import FileObject from "./FileObject.js"
|
|
4
|
-
import Sass from "./Sass.js"
|
|
5
|
-
import Util from "./Util.js"
|
|
6
|
-
import Valid from "./Valid.js"
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* Generic base class for managing hooks with configurable event types.
|
|
10
|
-
* Provides common functionality for hook registration, execution, and lifecycle management.
|
|
11
|
-
* Designed to be extended by specific implementations.
|
|
12
|
-
*/
|
|
13
|
-
export default class Hooks {
|
|
14
|
-
#hooksFile = null
|
|
15
|
-
#hooks = null
|
|
16
|
-
#actionKind = null
|
|
17
|
-
#timeout = 1000 // Default 1 second timeout
|
|
18
|
-
#debug = null
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* Creates a new BaseHookManager instance.
|
|
22
|
-
*
|
|
23
|
-
* @param {object} config - Configuration object
|
|
24
|
-
* @param {string} config.actionKind - Action identifier
|
|
25
|
-
* @param {FileObject} config.hooksFile - File object containing hooks with uri property
|
|
26
|
-
* @param {number} [config.hookTimeout] - Hook execution timeout in milliseconds
|
|
27
|
-
* @param {unknown} [config.hooks] - The hooks object
|
|
28
|
-
* @param {import('../types.js').DebugFunction} debug - Debug function from Glog.
|
|
29
|
-
*/
|
|
30
|
-
constructor({actionKind, hooksFile, hooks, hookTimeout = 1000}, debug) {
|
|
31
|
-
this.#actionKind = actionKind
|
|
32
|
-
this.#hooksFile = hooksFile
|
|
33
|
-
this.#hooks = hooks
|
|
34
|
-
this.#timeout = hookTimeout
|
|
35
|
-
this.#debug = debug
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
/**
|
|
39
|
-
* Gets the action identifier.
|
|
40
|
-
*
|
|
41
|
-
* @returns {string} Action identifier or instance
|
|
42
|
-
*/
|
|
43
|
-
get actionKind() {
|
|
44
|
-
return this.#actionKind
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
/**
|
|
48
|
-
* Gets the hooks file object.
|
|
49
|
-
*
|
|
50
|
-
* @returns {FileObject} File object containing hooks
|
|
51
|
-
*/
|
|
52
|
-
get hooksFile() {
|
|
53
|
-
return this.#hooksFile
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
/**
|
|
57
|
-
* Gets the loaded hooks object.
|
|
58
|
-
*
|
|
59
|
-
* @returns {object|null} Hooks object or null if not loaded
|
|
60
|
-
*/
|
|
61
|
-
get hooks() {
|
|
62
|
-
return this.#hooks
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
/**
|
|
66
|
-
* Gets the hook execution timeout in milliseconds.
|
|
67
|
-
*
|
|
68
|
-
* @returns {number} Timeout in milliseconds
|
|
69
|
-
*/
|
|
70
|
-
get timeout() {
|
|
71
|
-
return this.#timeout
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
/**
|
|
75
|
-
* Gets the setup hook function if available.
|
|
76
|
-
*
|
|
77
|
-
* @returns {(args: object) => unknown|null} Setup hook function or null
|
|
78
|
-
*/
|
|
79
|
-
get setup() {
|
|
80
|
-
return this.hooks?.setup || null
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
/**
|
|
84
|
-
* Gets the cleanup hook function if available.
|
|
85
|
-
*
|
|
86
|
-
* @returns {(args: object) => unknown|null} Cleanup hook function or null
|
|
87
|
-
*/
|
|
88
|
-
get cleanup() {
|
|
89
|
-
return this.hooks?.cleanup || null
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
/**
|
|
93
|
-
* Static factory method to create and initialize a hook manager.
|
|
94
|
-
* Loads hooks from the specified file and returns an initialized instance.
|
|
95
|
-
* Override loadHooks() in subclasses to customize hook loading logic.
|
|
96
|
-
*
|
|
97
|
-
* @param {object} config - Same configuration object as constructor
|
|
98
|
-
* @param {string|object} config.actionKind - Action identifier or instance
|
|
99
|
-
* @param {FileObject} config.hooksFile - File object containing hooks with uri property
|
|
100
|
-
* @param {number} [config.timeOut] - Hook execution timeout in milliseconds
|
|
101
|
-
* @param {import('../types.js').DebugFunction} debug - The debug function.
|
|
102
|
-
* @returns {Promise<Hooks|null>} Initialized hook manager or null if no hooks found
|
|
103
|
-
*/
|
|
104
|
-
static async new(config, debug) {
|
|
105
|
-
debug("Creating new HookManager instance with args: %o", 2, config)
|
|
106
|
-
|
|
107
|
-
const instance = new this(config, debug)
|
|
108
|
-
const hooksFile = instance.hooksFile
|
|
109
|
-
|
|
110
|
-
debug("Loading hooks from %o", 2, hooksFile.uri)
|
|
111
|
-
|
|
112
|
-
debug("Checking hooks file exists: %o", 2, hooksFile.uri)
|
|
113
|
-
if(!await hooksFile.exists)
|
|
114
|
-
throw Sass.new(`No such hooks file, ${hooksFile.uri}`)
|
|
115
|
-
|
|
116
|
-
try {
|
|
117
|
-
const hooksImport = await hooksFile.import()
|
|
118
|
-
|
|
119
|
-
if(!hooksImport)
|
|
120
|
-
return null
|
|
121
|
-
|
|
122
|
-
debug("Hooks file imported successfully as a module", 2)
|
|
123
|
-
|
|
124
|
-
const actionKind = instance.actionKind
|
|
125
|
-
if(!hooksImport[actionKind])
|
|
126
|
-
return null
|
|
127
|
-
|
|
128
|
-
const hooks = new hooksImport[actionKind]({debug})
|
|
129
|
-
|
|
130
|
-
debug(hooks.constructor.name, 4)
|
|
131
|
-
|
|
132
|
-
// Attach common properties to hooks
|
|
133
|
-
instance.#hooks = hooks
|
|
134
|
-
|
|
135
|
-
debug("Hooks %o loaded successfully for %o", 2, hooksFile.uri, instance.actionKind)
|
|
136
|
-
|
|
137
|
-
return instance
|
|
138
|
-
} catch(error) {
|
|
139
|
-
debug("Failed to load hooks %o: %o", 1, hooksFile.uri, error.message)
|
|
140
|
-
|
|
141
|
-
return null
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
async callHook(kind, activityName, context) {
|
|
146
|
-
try {
|
|
147
|
-
const debug = this.#debug
|
|
148
|
-
const hooks = this.#hooks
|
|
149
|
-
|
|
150
|
-
if(!hooks)
|
|
151
|
-
return
|
|
152
|
-
|
|
153
|
-
const hookName = `${kind}$${activityName}`
|
|
154
|
-
|
|
155
|
-
debug("Looking for hook: %o", 4, hookName)
|
|
156
|
-
|
|
157
|
-
const hook = hooks[hookName]
|
|
158
|
-
if(!hook)
|
|
159
|
-
return
|
|
160
|
-
|
|
161
|
-
debug("Triggering hook: %o", 4, hookName)
|
|
162
|
-
Valid.type(hook, "Function", `Hook "${hookName}" is not a function`)
|
|
163
|
-
|
|
164
|
-
const hookFunction = async() => {
|
|
165
|
-
debug("Hook function starting execution: %o", 4, hookName)
|
|
166
|
-
|
|
167
|
-
const duration = (await Util.time(() => hook.call(this.#hooks, context))).cost
|
|
168
|
-
|
|
169
|
-
debug("Hook function completed successfully: %o, after %oms", 4, hookName, duration)
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
const hookTimeout = this.timeout
|
|
173
|
-
const expireAsync = (async() => {
|
|
174
|
-
await timeout(hookTimeout)
|
|
175
|
-
throw Sass.new(`Hook ${hookName} execution exceeded timeout of ${hookTimeout}ms`)
|
|
176
|
-
})()
|
|
177
|
-
|
|
178
|
-
try {
|
|
179
|
-
debug("Starting Promise race for hook: %o", 4, hookName)
|
|
180
|
-
await Util.race([
|
|
181
|
-
hookFunction(),
|
|
182
|
-
expireAsync
|
|
183
|
-
])
|
|
184
|
-
} catch(error) {
|
|
185
|
-
throw Sass.new(`Processing hook ${kind}$${activityName}`, error)
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
debug("We made it throoough the wildernessss", 4)
|
|
189
|
-
|
|
190
|
-
} catch(error) {
|
|
191
|
-
throw Sass.new(`Processing hook ${kind}$${activityName}`, error)
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
}
|
package/src/lib/Piper.js
DELETED
|
@@ -1,155 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Generic Pipeline - Process items through a series of steps with concurrency control
|
|
3
|
-
*
|
|
4
|
-
* This abstraction handles:
|
|
5
|
-
* - Concurrent processing with configurable limits
|
|
6
|
-
* - Pipeline of processing steps
|
|
7
|
-
* - Result categorization (success/warning/error)
|
|
8
|
-
* - Setup/cleanup lifecycle hooks
|
|
9
|
-
* - Error handling and reporting
|
|
10
|
-
*/
|
|
11
|
-
|
|
12
|
-
import Glog from "./Glog.js"
|
|
13
|
-
import Sass from "./Sass.js"
|
|
14
|
-
import Tantrum from "./Tantrum.js"
|
|
15
|
-
import Util from "./Util.js"
|
|
16
|
-
|
|
17
|
-
export default class Piper {
|
|
18
|
-
#debug
|
|
19
|
-
|
|
20
|
-
#lifeCycle = new Map([
|
|
21
|
-
["setup", new Set()],
|
|
22
|
-
["process", new Set()],
|
|
23
|
-
["teardown", new Set()]
|
|
24
|
-
])
|
|
25
|
-
|
|
26
|
-
constructor(arg) {
|
|
27
|
-
this.#debug = arg?.debug ?? new Glog().newDebug("[PIPER]")
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* Add a processing step to the pipeline
|
|
32
|
-
*
|
|
33
|
-
* @param {(context: object) => Promise<object>} fn - Function that processes an item: (context) => Promise<result>
|
|
34
|
-
* @param {object} options - Step options (name, required, etc.)
|
|
35
|
-
* @returns {Piper} The pipeline instance (for chaining)
|
|
36
|
-
*/
|
|
37
|
-
addStep(fn, options = {}) {
|
|
38
|
-
this.#lifeCycle.get("process").add({
|
|
39
|
-
fn,
|
|
40
|
-
name: options.name || `Step ${this.#lifeCycle.get("process").size + 1}`,
|
|
41
|
-
required: !!options.required, // Default to required
|
|
42
|
-
...options
|
|
43
|
-
})
|
|
44
|
-
|
|
45
|
-
return this
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
/**
|
|
49
|
-
* Add setup hook that runs before processing starts
|
|
50
|
-
*
|
|
51
|
-
* @param {() => Promise<void>} fn - Setup function: () => Promise<void>
|
|
52
|
-
* @returns {Piper} The pipeline instance (for chaining)
|
|
53
|
-
*/
|
|
54
|
-
addSetup(fn) {
|
|
55
|
-
this.#lifeCycle.get("setup").add(fn)
|
|
56
|
-
|
|
57
|
-
return this
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
/**
|
|
61
|
-
* Add cleanup hook that runs after processing completes
|
|
62
|
-
*
|
|
63
|
-
* @param {() => Promise<void>} fn - Cleanup function: () => Promise<void>
|
|
64
|
-
* @returns {Piper} The pipeline instance (for chaining)
|
|
65
|
-
*/
|
|
66
|
-
addCleanup(fn) {
|
|
67
|
-
this.#lifeCycle.get("teardown").add(fn)
|
|
68
|
-
|
|
69
|
-
return this
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
/**
|
|
73
|
-
* Process items through the pipeline with concurrency control
|
|
74
|
-
*
|
|
75
|
-
* @param {Array} items - Items to process
|
|
76
|
-
* @param {number} maxConcurrent - Maximum concurrent items to process
|
|
77
|
-
* @returns {Promise<object>} - Results object with succeeded, warned, errored arrays
|
|
78
|
-
*/
|
|
79
|
-
async pipe(items, maxConcurrent = 10) {
|
|
80
|
-
items.forEach(item => item.pipeStamp = Symbol(performance.now()))
|
|
81
|
-
|
|
82
|
-
let itemIndex = 0
|
|
83
|
-
const allResults = []
|
|
84
|
-
|
|
85
|
-
const processWorker = async() => {
|
|
86
|
-
while(true) {
|
|
87
|
-
const currentIndex = itemIndex++
|
|
88
|
-
if(currentIndex >= items.length)
|
|
89
|
-
break
|
|
90
|
-
|
|
91
|
-
const item = items[currentIndex]
|
|
92
|
-
try {
|
|
93
|
-
const result = await this.#processItem(item)
|
|
94
|
-
allResults.push(result)
|
|
95
|
-
} catch(error) {
|
|
96
|
-
throw Sass.new("Processing pipeline item.", error)
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
const setupResult = await Util.settleAll([...this.#lifeCycle.get("setup")].map(e => e()))
|
|
102
|
-
this.#processResult("Setting up the pipeline.", setupResult)
|
|
103
|
-
|
|
104
|
-
// Start workers up to maxConcurrent limit
|
|
105
|
-
const workers = []
|
|
106
|
-
const workerCount = Math.min(maxConcurrent, items.length)
|
|
107
|
-
|
|
108
|
-
for(let i = 0; i < workerCount; i++)
|
|
109
|
-
workers.push(processWorker())
|
|
110
|
-
|
|
111
|
-
// Wait for all workers to complete
|
|
112
|
-
const processResult = await Util.settleAll(workers)
|
|
113
|
-
this.#processResult("Processing pipeline.", processResult)
|
|
114
|
-
|
|
115
|
-
// Run cleanup hooks
|
|
116
|
-
const teardownResult = await Util.settleAll([...this.#lifeCycle.get("teardown")].map(e => e()))
|
|
117
|
-
this.#processResult("Tearing down the pipeline.", teardownResult)
|
|
118
|
-
|
|
119
|
-
return allResults
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
#processResult(message, settled) {
|
|
123
|
-
if(settled.some(r => r.status === "rejected"))
|
|
124
|
-
throw Tantrum.new(
|
|
125
|
-
message,
|
|
126
|
-
settled.filter(r => r.status==="rejected").map(r => r.reason)
|
|
127
|
-
)
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
/**
|
|
131
|
-
* Process a single item through all pipeline steps
|
|
132
|
-
*
|
|
133
|
-
* @param {object} item - The item to process
|
|
134
|
-
* @returns {Promise<object>} Result object with status and data
|
|
135
|
-
* @private
|
|
136
|
-
*/
|
|
137
|
-
async #processItem(item) {
|
|
138
|
-
const debug = this.#debug
|
|
139
|
-
|
|
140
|
-
try {
|
|
141
|
-
// Execute each step in sequence
|
|
142
|
-
let result = item
|
|
143
|
-
|
|
144
|
-
for(const step of this.#lifeCycle.get("process")) {
|
|
145
|
-
debug("Executing step: %o", 2, step.name)
|
|
146
|
-
|
|
147
|
-
result = await step.fn(result) ?? result
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
return result
|
|
151
|
-
} catch(error) {
|
|
152
|
-
throw Sass.new("Processing an item.", error)
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
}
|