fable 3.0.91 → 3.0.93
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/fable.compatible.js +24 -20
- package/dist/fable.compatible.min.js +1 -1
- package/dist/fable.compatible.min.js.map +1 -1
- package/dist/fable.js +23 -19
- package/dist/fable.min.js +1 -1
- package/dist/fable.min.js.map +1 -1
- package/package.json +1 -1
- package/source/services/Fable-Service-MetaTemplate/MetaTemplate-StringParser.js +57 -55
- package/source/services/Fable-Service-MetaTemplate/MetaTemplate-WordTree.js +21 -2
- package/source/services/Fable-Service-MetaTemplate.js +5 -0
- package/test/MetaTemplating_tests.js +29 -0
package/package.json
CHANGED
|
@@ -105,12 +105,17 @@ class StringParser
|
|
|
105
105
|
// Flush the output buffer.
|
|
106
106
|
this.appendOutputBuffer(pCharacter, pParserState);
|
|
107
107
|
// If this last character is the end of the pattern, parse it.
|
|
108
|
-
if (pParserState.Pattern.hasOwnProperty('Parse'))
|
|
108
|
+
if (pParserState.Pattern.hasOwnProperty('Parse') && (!pParserState.Pattern.isAsync || pParserState.Pattern.isBoth))
|
|
109
109
|
{
|
|
110
110
|
// Run the function
|
|
111
111
|
pParserState.OutputBuffer = pParserState.Pattern.Parse(pParserState.OutputBuffer.substr(pParserState.Pattern.PatternStartString.length, pParserState.OutputBuffer.length - (pParserState.Pattern.PatternStartString.length+pParserState.Pattern.PatternEndString.length)), pData);
|
|
112
112
|
return this.resetOutputBuffer(pParserState);
|
|
113
113
|
}
|
|
114
|
+
else
|
|
115
|
+
{
|
|
116
|
+
console.log(`MetaTemplate: The pattern ${pParserState.Pattern.PatternStartString} is asynchronous and cannot be used in a synchronous parser.`);
|
|
117
|
+
return this.resetOutputBuffer(pParserState);
|
|
118
|
+
}
|
|
114
119
|
}
|
|
115
120
|
else if (pParserState.PatternStartNode.PatternEnd.hasOwnProperty(pCharacter))
|
|
116
121
|
{
|
|
@@ -143,9 +148,9 @@ class StringParser
|
|
|
143
148
|
// If this last character is the end of the pattern, parse it.
|
|
144
149
|
if (pParserState.Pattern.hasOwnProperty('Parse'))
|
|
145
150
|
{
|
|
146
|
-
if (pParserState.Pattern.isAsync)
|
|
151
|
+
if (pParserState.Pattern.isAsync && !pParserState.Pattern.isBoth)
|
|
147
152
|
{
|
|
148
|
-
|
|
153
|
+
console.log(`MetaTemplate: The pattern ${pParserState.Pattern.PatternStartString} is asynchronous and cannot be used in a synchronous parser.`);
|
|
149
154
|
this.resetOutputBuffer(pParserState);
|
|
150
155
|
}
|
|
151
156
|
else
|
|
@@ -184,6 +189,52 @@ class StringParser
|
|
|
184
189
|
return false;
|
|
185
190
|
}
|
|
186
191
|
|
|
192
|
+
executePatternAsync(pParserState, pData, fCallback)
|
|
193
|
+
{
|
|
194
|
+
// ... this is the end of a pattern, cut off the end tag and parse it.
|
|
195
|
+
// Trim the start and end tags off the output buffer now
|
|
196
|
+
if (pParserState.Pattern.isAsync && !pParserState.Pattern.isBoth)
|
|
197
|
+
{
|
|
198
|
+
// Run the function
|
|
199
|
+
return pParserState.Pattern.Parse(pParserState.OutputBuffer.substr(pParserState.Pattern.PatternStartString.length, pParserState.OutputBuffer.length - (pParserState.Pattern.PatternStartString.length+pParserState.Pattern.PatternEndString.length)), pData,
|
|
200
|
+
(pError, pAsyncOutput) =>
|
|
201
|
+
{
|
|
202
|
+
if (pError)
|
|
203
|
+
{
|
|
204
|
+
console.log(`Precedent ERROR: Async template error happened parsing ${pParserState.Pattern.PatternStart} ... ${pParserState.Pattern.PatternEnd}: ${pError}`);
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
pParserState.OutputBuffer = pAsyncOutput;
|
|
208
|
+
this.resetOutputBuffer(pParserState);
|
|
209
|
+
return fCallback();
|
|
210
|
+
});
|
|
211
|
+
}
|
|
212
|
+
else if (pParserState.Pattern.isAsync && pParserState.Pattern.isBoth)
|
|
213
|
+
{
|
|
214
|
+
// Run the function when both async and non async were provided with the pattern
|
|
215
|
+
return pParserState.Pattern.ParseAsync(pParserState.OutputBuffer.substr(pParserState.Pattern.PatternStartString.length, pParserState.OutputBuffer.length - (pParserState.Pattern.PatternStartString.length+pParserState.Pattern.PatternEndString.length)), pData,
|
|
216
|
+
(pError, pAsyncOutput) =>
|
|
217
|
+
{
|
|
218
|
+
if (pError)
|
|
219
|
+
{
|
|
220
|
+
console.log(`Precedent ERROR: Async template error happened parsing ${pParserState.Pattern.PatternStart} ... ${pParserState.Pattern.PatternEnd}: ${pError}`);
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
pParserState.OutputBuffer = pAsyncOutput;
|
|
224
|
+
this.resetOutputBuffer(pParserState);
|
|
225
|
+
return fCallback();
|
|
226
|
+
});
|
|
227
|
+
}
|
|
228
|
+
else
|
|
229
|
+
{
|
|
230
|
+
// Run the t*mplate function
|
|
231
|
+
pParserState.OutputBuffer = pParserState.Pattern.Parse(pParserState.OutputBuffer.substr(pParserState.Pattern.PatternStartString.length, pParserState.OutputBuffer.length - (pParserState.Pattern.PatternStartString.length+pParserState.Pattern.PatternEndString.length)), pData);
|
|
232
|
+
this.resetOutputBuffer(pParserState);
|
|
233
|
+
return fCallback();
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
|
|
187
238
|
/**
|
|
188
239
|
* Parse a character in the buffer.
|
|
189
240
|
* @method parseCharacter
|
|
@@ -213,31 +264,7 @@ class StringParser
|
|
|
213
264
|
// If this last character is the end of the pattern, parse it.
|
|
214
265
|
if (pParserState.Pattern.hasOwnProperty('Parse'))
|
|
215
266
|
{
|
|
216
|
-
|
|
217
|
-
// Trim the start and end tags off the output buffer now
|
|
218
|
-
if (pParserState.Pattern.isAsync)
|
|
219
|
-
{
|
|
220
|
-
// Run the function
|
|
221
|
-
return pParserState.Pattern.Parse(pParserState.OutputBuffer.substr(pParserState.Pattern.PatternStartString.length, pParserState.OutputBuffer.length - (pParserState.Pattern.PatternStartString.length+pParserState.Pattern.PatternEndString.length)), pData,
|
|
222
|
-
(pError, pAsyncOutput) =>
|
|
223
|
-
{
|
|
224
|
-
if (pError)
|
|
225
|
-
{
|
|
226
|
-
console.log(`Precedent ERROR: Async template error happened parsing ${pParserState.Pattern.PatternStart} ... ${pParserState.Pattern.PatternEnd}: ${pError}`);
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
pParserState.OutputBuffer = pAsyncOutput;
|
|
230
|
-
this.resetOutputBuffer(pParserState);
|
|
231
|
-
return fCallback();
|
|
232
|
-
});
|
|
233
|
-
}
|
|
234
|
-
else
|
|
235
|
-
{
|
|
236
|
-
// Run the t*mplate function
|
|
237
|
-
pParserState.OutputBuffer = pParserState.Pattern.Parse(pParserState.OutputBuffer.substr(pParserState.Pattern.PatternStartString.length, pParserState.OutputBuffer.length - (pParserState.Pattern.PatternStartString.length+pParserState.Pattern.PatternEndString.length)), pData);
|
|
238
|
-
this.resetOutputBuffer(pParserState);
|
|
239
|
-
return fCallback();
|
|
240
|
-
}
|
|
267
|
+
return this.executePatternAsync(pParserState, pData, fCallback);
|
|
241
268
|
}
|
|
242
269
|
}
|
|
243
270
|
else if (pParserState.PatternStartNode.PatternEnd.hasOwnProperty(pCharacter))
|
|
@@ -271,31 +298,7 @@ class StringParser
|
|
|
271
298
|
// If this last character is the end of the pattern, parse it.
|
|
272
299
|
if (pParserState.Pattern.hasOwnProperty('Parse'))
|
|
273
300
|
{
|
|
274
|
-
|
|
275
|
-
// Trim the start and end tags off the output buffer now
|
|
276
|
-
if (pParserState.Pattern.isAsync)
|
|
277
|
-
{
|
|
278
|
-
// Run the function
|
|
279
|
-
return pParserState.Pattern.Parse(pParserState.OutputBuffer.substr(pParserState.Pattern.PatternStartString.length, pParserState.OutputBuffer.length - (pParserState.Pattern.PatternStartString.length+pParserState.Pattern.PatternEndString.length)), pData,
|
|
280
|
-
(pError, pAsyncOutput) =>
|
|
281
|
-
{
|
|
282
|
-
if (pError)
|
|
283
|
-
{
|
|
284
|
-
console.log(`Precedent ERROR: Async template error happened parsing ${pParserState.Pattern.PatternStart} ... ${pParserState.Pattern.PatternEnd}: ${pError}`);
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
pParserState.OutputBuffer = pAsyncOutput;
|
|
288
|
-
this.resetOutputBuffer(pParserState);
|
|
289
|
-
return fCallback();
|
|
290
|
-
});
|
|
291
|
-
}
|
|
292
|
-
else
|
|
293
|
-
{
|
|
294
|
-
// Run the t*mplate function
|
|
295
|
-
pParserState.OutputBuffer = pParserState.Pattern.Parse(pParserState.OutputBuffer.substr(pParserState.Pattern.PatternStartString.length, pParserState.OutputBuffer.length - (pParserState.Pattern.PatternStartString.length+pParserState.Pattern.PatternEndString.length)), pData);
|
|
296
|
-
this.resetOutputBuffer(pParserState);
|
|
297
|
-
return fCallback();
|
|
298
|
-
}
|
|
301
|
+
return this.executePatternAsync(pParserState, pData, fCallback);
|
|
299
302
|
}
|
|
300
303
|
}
|
|
301
304
|
}
|
|
@@ -303,11 +306,10 @@ class StringParser
|
|
|
303
306
|
{
|
|
304
307
|
// We are in a pattern start but didn't match one; reset and start trying again from this character.
|
|
305
308
|
this.resetOutputBuffer(pParserState);
|
|
306
|
-
return fCallback();
|
|
307
309
|
}
|
|
308
310
|
}
|
|
309
311
|
// If we aren't in a pattern match or pattern, and this isn't the start of a new pattern (RAW mode)....
|
|
310
|
-
|
|
312
|
+
else
|
|
311
313
|
{
|
|
312
314
|
// This may be the start of a new pattern....
|
|
313
315
|
if (pParserState.ParseTree.hasOwnProperty(pCharacter))
|
|
@@ -101,18 +101,37 @@ class WordTree
|
|
|
101
101
|
|
|
102
102
|
|
|
103
103
|
/** Add a Pattern to the Parse Tree
|
|
104
|
-
* @method
|
|
104
|
+
* @method addPatternAsync
|
|
105
|
+
* @param {Object} pPatternStart - The starting string for the pattern (e.g. "${")
|
|
106
|
+
* @param {string} pPatternEnd - The ending string for the pattern (e.g. "}")
|
|
107
|
+
* @param {function} fParserAsync - The function to parse if this is the matched pattern, once the Pattern End is met. If this is a string, a simple replacement occurs.
|
|
108
|
+
* @return {bool} True if adding the pattern was successful
|
|
109
|
+
*/
|
|
110
|
+
addPatternAsync (pPatternStart, pPatternEnd, fParserAsync)
|
|
111
|
+
{
|
|
112
|
+
let tmpLeaf = this.addPattern(pPatternStart, pPatternEnd, fParserAsync);
|
|
113
|
+
if (tmpLeaf)
|
|
114
|
+
{
|
|
115
|
+
tmpLeaf.isAsync = true;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/** Add a Pattern to the Parse Tree
|
|
120
|
+
* @method addPatternBoth
|
|
105
121
|
* @param {Object} pPatternStart - The starting string for the pattern (e.g. "${")
|
|
106
122
|
* @param {string} pPatternEnd - The ending string for the pattern (e.g. "}")
|
|
107
123
|
* @param {function} fParser - The function to parse if this is the matched pattern, once the Pattern End is met. If this is a string, a simple replacement occurs.
|
|
108
124
|
* @return {bool} True if adding the pattern was successful
|
|
109
125
|
*/
|
|
110
|
-
|
|
126
|
+
addPatternBoth (pPatternStart, pPatternEnd, fParser, fParserAsync)
|
|
111
127
|
{
|
|
112
128
|
let tmpLeaf = this.addPattern(pPatternStart, pPatternEnd, fParser);
|
|
113
129
|
if (tmpLeaf)
|
|
114
130
|
{
|
|
115
131
|
tmpLeaf.isAsync = true;
|
|
132
|
+
tmpLeaf.isBoth = true;
|
|
133
|
+
// When a leaf has both async and non-async versions of the functions, we store the async in fParserAsync.
|
|
134
|
+
tmpLeaf.ParseAsync = fParserAsync;
|
|
116
135
|
}
|
|
117
136
|
}
|
|
118
137
|
}
|
|
@@ -44,6 +44,11 @@ class FableServiceMetaTemplate extends libFableServiceBase
|
|
|
44
44
|
return this.WordTree.addPatternAsync(pPatternStart, pPatternEnd, pParserPromise);
|
|
45
45
|
}
|
|
46
46
|
|
|
47
|
+
addPatternBoth(pPatternStart, pPatternEnd, pParser, pParserPromise)
|
|
48
|
+
{
|
|
49
|
+
return this.WordTree.addPatternBoth(pPatternStart, pPatternEnd, pParser, pParserPromise);
|
|
50
|
+
}
|
|
51
|
+
|
|
47
52
|
/**
|
|
48
53
|
* Parse a string with the existing parse tree
|
|
49
54
|
* @method parseString
|
|
@@ -37,6 +37,16 @@ const configMetaTemplate = (pModule) =>
|
|
|
37
37
|
{
|
|
38
38
|
return fCallback(null, `ASYNC DATA IS [${pHash}]`);
|
|
39
39
|
});
|
|
40
|
+
|
|
41
|
+
pModule.addPatternBoth('<~', '~>',
|
|
42
|
+
(pHash, pData) =>
|
|
43
|
+
{
|
|
44
|
+
return `Non-Async Jellyfish called for pData which is [${pData}] with a hash of [${pHash}]`
|
|
45
|
+
},
|
|
46
|
+
(pHash, pData, fCallback)=>
|
|
47
|
+
{
|
|
48
|
+
return fCallback(null, `Async Jellyfish called for pData which is [${pData}] with a hash of [${pHash}]`);
|
|
49
|
+
});
|
|
40
50
|
|
|
41
51
|
};
|
|
42
52
|
|
|
@@ -160,6 +170,25 @@ suite
|
|
|
160
170
|
}
|
|
161
171
|
);
|
|
162
172
|
test
|
|
173
|
+
(
|
|
174
|
+
'Passing both Async and Non-async Function',
|
|
175
|
+
(fDone) =>
|
|
176
|
+
{
|
|
177
|
+
let tmpTestString = 'The <^SomeValue^> and <~JELLY FISH~> pData and Async <%AsyncThe Funny String%> up in here and a $comment$ as well.';
|
|
178
|
+
let tmpExpectedResultAsync = 'The hash of [SomeValue] from pData is AirbornLight and Async Jellyfish called for pData which is [[object Object]] with a hash of [JELLY FISH] pData and Async ASYNC DATA IS [The Funny String] up in here and a comment as well.';
|
|
179
|
+
let tmpExpectedResult = 'The hash of [SomeValue] from pData is AirbornLight and Non-Async Jellyfish called for pData which is [[object Object]] with a hash of [JELLY FISH] pData and Async <%AsyncThe Funny String%> up in here and a comment as well.';
|
|
180
|
+
let testMetaTemplate = loadMetaTemplateModule();
|
|
181
|
+
configMetaTemplate(testMetaTemplate);
|
|
182
|
+
let tmpNonAsyncResult = testMetaTemplate.parseString(tmpTestString, {SomeValue:'AirbornLight'});
|
|
183
|
+
Expect(tmpNonAsyncResult).to.equal(tmpExpectedResult);
|
|
184
|
+
let tmpResult = testMetaTemplate.parseString(tmpTestString, {SomeValue:'AirbornLight'},
|
|
185
|
+
(pError, pValue) =>
|
|
186
|
+
{
|
|
187
|
+
Expect(pValue).to.equal(tmpExpectedResultAsync);
|
|
188
|
+
return fDone();
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
); test
|
|
163
192
|
(
|
|
164
193
|
'Bad pattern start parameter...',
|
|
165
194
|
(fDone) =>
|