wingbot 3.52.6 → 3.53.0-alpha.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/package.json +1 -1
- package/plugins/ai.wingbot.clearMessageSequences/README.md +1 -0
- package/plugins/ai.wingbot.clearMessageSequences/plugin.js +13 -0
- package/plugins/ai.wingbot.regexp/README.md +1 -9
- package/plugins/plugins.json +14 -0
- package/src/BuildRouter.js +4 -1
- package/src/Processor.js +3 -1
- package/src/Tester.js +20 -4
- package/src/resolvers/message.js +94 -10
- package/src/resolvers/utils.js +6 -0
- package/src/utils/stateVariables.js +95 -9
package/package.json
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
> This plugin erases state of conversational sequences
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @param {import('../../src/Request')} req
|
|
3
|
+
* @param {import('../../src/Responder')} res
|
|
4
|
+
*/
|
|
5
|
+
module.exports = async (req, res) => {
|
|
6
|
+
[...Object.keys(req.state), ...Object.keys(res.newState)]
|
|
7
|
+
.forEach((key) => {
|
|
8
|
+
const match = key.match(/^(_~_R_|_R_)/);
|
|
9
|
+
if (match) {
|
|
10
|
+
res.setState({ [key]: null });
|
|
11
|
+
}
|
|
12
|
+
});
|
|
13
|
+
};
|
|
@@ -1,9 +1 @@
|
|
|
1
|
-
> This plugin
|
|
2
|
-
|
|
3
|
-
If the previous interaction exists and it's not a fallback or the same interaction, where the plugin is, the bot will go back and stops executing this interaction.
|
|
4
|
-
|
|
5
|
-
If not, the bot will continue in execution of this interaction, so you can handle situation.
|
|
6
|
-
|
|
7
|
-
It's useful to it use **Show when there is a way back** condition, so you don't have to worry about handling the situation, when there's no way to go back.
|
|
8
|
-
|
|
9
|
-

|
|
1
|
+
> This plugin detects reqular expressions
|
package/plugins/plugins.json
CHANGED
|
@@ -446,6 +446,7 @@
|
|
|
446
446
|
"availableSince": 3.39,
|
|
447
447
|
"editable": false,
|
|
448
448
|
"isFactory": true,
|
|
449
|
+
"category": "conversation",
|
|
449
450
|
"inputs": [
|
|
450
451
|
{
|
|
451
452
|
"name": "skip",
|
|
@@ -470,6 +471,19 @@
|
|
|
470
471
|
],
|
|
471
472
|
"items": [
|
|
472
473
|
]
|
|
474
|
+
},
|
|
475
|
+
{
|
|
476
|
+
"id": "ai.wingbot.clearMessageSequences",
|
|
477
|
+
"name": "Clear message sequences state",
|
|
478
|
+
"description": "Put it in a first interaction of the process, where would you like to have clear states of messages sequences",
|
|
479
|
+
"availableSince": 3.53,
|
|
480
|
+
"editable": true,
|
|
481
|
+
"isFactory": false,
|
|
482
|
+
"category": "conversation",
|
|
483
|
+
"inputs": [
|
|
484
|
+
],
|
|
485
|
+
"items": [
|
|
486
|
+
]
|
|
473
487
|
}
|
|
474
488
|
],
|
|
475
489
|
"categories": [
|
package/src/BuildRouter.js
CHANGED
|
@@ -26,6 +26,7 @@ const MESSAGE_RESOLVER_NAME = 'botbuild.message';
|
|
|
26
26
|
|
|
27
27
|
/**
|
|
28
28
|
* @typedef {object} Resolver
|
|
29
|
+
* @prop {string|number} [id] - only for text messages with random characters
|
|
29
30
|
* @prop {string} type
|
|
30
31
|
* @prop {object} params
|
|
31
32
|
* @prop {string} [params.staticBlockId]
|
|
@@ -132,6 +133,7 @@ const DUMMY_ROUTE = { id: 0, path: null, resolvers: [] };
|
|
|
132
133
|
* @prop {string} [staticBlockId]
|
|
133
134
|
* @prop {Block[]} [blocks]
|
|
134
135
|
* @prop {object} [BuildRouter]
|
|
136
|
+
* @prop {string} [resolverId] - only for text messages with random characters
|
|
135
137
|
*/
|
|
136
138
|
|
|
137
139
|
/**
|
|
@@ -827,7 +829,8 @@ class BuildRouter extends Router {
|
|
|
827
829
|
isResponder,
|
|
828
830
|
expectedPath,
|
|
829
831
|
routeId: id,
|
|
830
|
-
configuration: this._configuration
|
|
832
|
+
configuration: this._configuration,
|
|
833
|
+
resolverId: resolver.id
|
|
831
834
|
};
|
|
832
835
|
|
|
833
836
|
const resFn = this._resolverFactory(resolver, context, buildInfo);
|
package/src/Processor.js
CHANGED
|
@@ -10,7 +10,7 @@ const Responder = require('./Responder');
|
|
|
10
10
|
const Request = require('./Request');
|
|
11
11
|
const Ai = require('./Ai');
|
|
12
12
|
const ReturnSender = require('./ReturnSender');
|
|
13
|
-
const { mergeState, isUserInteraction } = require('./utils/stateVariables');
|
|
13
|
+
const { prepareState, mergeState, isUserInteraction } = require('./utils/stateVariables');
|
|
14
14
|
|
|
15
15
|
/** @typedef {import('./wingbot/CustomEntityDetectionModel').Intent} Intent */
|
|
16
16
|
/** @typedef {import('./ReducerWrapper')} ReducerWrapper */
|
|
@@ -637,6 +637,8 @@ class Processor extends EventEmitter {
|
|
|
637
637
|
});
|
|
638
638
|
}
|
|
639
639
|
|
|
640
|
+
prepareState(state, fromEvent, state._snew);
|
|
641
|
+
|
|
640
642
|
const features = [
|
|
641
643
|
...(this.options.features || []),
|
|
642
644
|
...req.features
|
package/src/Tester.js
CHANGED
|
@@ -18,6 +18,8 @@ const Router = require('./Router'); // eslint-disable-line no-unused-vars
|
|
|
18
18
|
const ReducerWrapper = require('./ReducerWrapper'); // eslint-disable-line no-unused-vars
|
|
19
19
|
const { FEATURE_TEXT } = require('./features');
|
|
20
20
|
|
|
21
|
+
/** @typedef {import('./Processor').ProcessorOptions} ProcessorOptions */
|
|
22
|
+
|
|
21
23
|
/**
|
|
22
24
|
* Utility for testing requests
|
|
23
25
|
*
|
|
@@ -31,7 +33,7 @@ class Tester {
|
|
|
31
33
|
* @param {Router|ReducerWrapper} reducer
|
|
32
34
|
* @param {string} [senderId=null]
|
|
33
35
|
* @param {string} [pageId=null]
|
|
34
|
-
* @param {
|
|
36
|
+
* @param {ProcessorOptions} [processorOptions={}] - options for Processor
|
|
35
37
|
* @param {MemoryStateStorage} [storage] - place to override the storage
|
|
36
38
|
*
|
|
37
39
|
* @memberOf Tester
|
|
@@ -95,6 +97,7 @@ class Tester {
|
|
|
95
97
|
this.processor = new Processor(reducer, ({
|
|
96
98
|
stateStorage: this.storage,
|
|
97
99
|
log,
|
|
100
|
+
// @ts-ignore
|
|
98
101
|
loadUsers: false,
|
|
99
102
|
...processorOptions
|
|
100
103
|
}));
|
|
@@ -168,10 +171,12 @@ class Tester {
|
|
|
168
171
|
/**
|
|
169
172
|
* Enable tester to expand random texts
|
|
170
173
|
* It joins them into a single sting
|
|
174
|
+
*
|
|
175
|
+
* @param {boolean} [fixedIndex]
|
|
171
176
|
*/
|
|
172
|
-
setExpandRandomTexts () {
|
|
177
|
+
setExpandRandomTexts (fixedIndex) {
|
|
173
178
|
Object.assign(this.testData, {
|
|
174
|
-
_expandRandomTexts: true
|
|
179
|
+
_expandRandomTexts: fixedIndex ? 1 : true
|
|
175
180
|
});
|
|
176
181
|
}
|
|
177
182
|
|
|
@@ -381,9 +386,20 @@ class Tester {
|
|
|
381
386
|
stateContains (object, deep = false) {
|
|
382
387
|
const { state } = this.getState();
|
|
383
388
|
|
|
389
|
+
const clean = Object.fromEntries(
|
|
390
|
+
Object.entries(object)
|
|
391
|
+
.filter(([k, v]) => {
|
|
392
|
+
if (v === null || v === undefined) {
|
|
393
|
+
assert.ok(state[k] === null || state[k] === undefined, `Expected state key '${k}' to be empty. Actual: ${JSON.stringify(state[k])}'`);
|
|
394
|
+
return false;
|
|
395
|
+
}
|
|
396
|
+
return true;
|
|
397
|
+
})
|
|
398
|
+
);
|
|
399
|
+
|
|
384
400
|
assert.deepEqual(
|
|
385
401
|
state,
|
|
386
|
-
deep ? deepExtend({}, state,
|
|
402
|
+
deep ? deepExtend({}, state, clean) : { ...state, ...clean },
|
|
387
403
|
'Conversation state equals'
|
|
388
404
|
);
|
|
389
405
|
}
|
package/src/resolvers/message.js
CHANGED
|
@@ -13,11 +13,13 @@ const {
|
|
|
13
13
|
getLanguageText,
|
|
14
14
|
getLanguageTextObjects,
|
|
15
15
|
randomizedCompiler,
|
|
16
|
-
cachedTranslatedCompilator
|
|
16
|
+
cachedTranslatedCompilator,
|
|
17
|
+
renderMessageText
|
|
17
18
|
} = require('./utils');
|
|
18
19
|
const {
|
|
19
20
|
FEATURE_SSML, FEATURE_TEXT, FEATURE_VOICE
|
|
20
21
|
} = require('../features');
|
|
22
|
+
const { vars, VAR_TYPES } = require('../utils/stateVariables');
|
|
21
23
|
|
|
22
24
|
/** @typedef {import('../Responder').VoiceControl} VoiceControl */
|
|
23
25
|
/** @typedef {import('./utils').Translations} Translations */
|
|
@@ -180,6 +182,89 @@ function findSupportedMessages (text, features, lang = null) {
|
|
|
180
182
|
};
|
|
181
183
|
}
|
|
182
184
|
|
|
185
|
+
const MODE_RANDOM = 'r';
|
|
186
|
+
const MODE_SEQUENCE = 's';
|
|
187
|
+
const MODE_RANDOM_START_SEQUENCE = 'rs';
|
|
188
|
+
|
|
189
|
+
const ALL_MODES = [MODE_RANDOM, MODE_SEQUENCE, MODE_RANDOM_START_SEQUENCE];
|
|
190
|
+
|
|
191
|
+
function selectTranslation (resolverId, params, texts, data) {
|
|
192
|
+
const key = `_R_${resolverId}`;
|
|
193
|
+
let { lang, [key]: seqState } = data;
|
|
194
|
+
|
|
195
|
+
if (texts.length === 1) {
|
|
196
|
+
return [
|
|
197
|
+
renderMessageText(texts[0].t, data),
|
|
198
|
+
seqState && resolverId ? { [key]: null } : {}
|
|
199
|
+
];
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
const { mode, persist = null } = params;
|
|
203
|
+
|
|
204
|
+
if ((!mode || mode === MODE_RANDOM) && data._expandRandomTexts === true) {
|
|
205
|
+
return [
|
|
206
|
+
texts.map((x) => renderMessageText(x.t, data))
|
|
207
|
+
.join('\n'),
|
|
208
|
+
{}
|
|
209
|
+
];
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
if (!lang) {
|
|
213
|
+
const [firstText = { l: null }] = getLanguageTextObjects(params.text);
|
|
214
|
+
lang = firstText.l || 'X';
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
if (mode === MODE_RANDOM || !ALL_MODES.includes(mode)) {
|
|
218
|
+
const index = data._expandRandomTexts
|
|
219
|
+
? 1
|
|
220
|
+
: Math.floor(Math.random() * texts.length);
|
|
221
|
+
return [
|
|
222
|
+
renderMessageText(texts[index].t, data),
|
|
223
|
+
seqState ? vars.clear(key) : {}
|
|
224
|
+
];
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
if (!seqState
|
|
228
|
+
|| seqState.l !== lang
|
|
229
|
+
|| seqState.n > texts.length
|
|
230
|
+
|| seqState.i >= texts.length) {
|
|
231
|
+
|
|
232
|
+
seqState = {
|
|
233
|
+
l: lang,
|
|
234
|
+
n: texts.length,
|
|
235
|
+
i: mode === MODE_SEQUENCE ? 0 : Math.floor(Math.random() * texts.length)
|
|
236
|
+
};
|
|
237
|
+
|
|
238
|
+
if (mode === MODE_RANDOM_START_SEQUENCE && data._expandRandomTexts) {
|
|
239
|
+
seqState.i = 1;
|
|
240
|
+
}
|
|
241
|
+
} else {
|
|
242
|
+
seqState = {
|
|
243
|
+
...seqState,
|
|
244
|
+
i: (seqState.i + 1) % texts.length
|
|
245
|
+
};
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
let setState;
|
|
249
|
+
|
|
250
|
+
if (persist === VAR_TYPES.SESSION_CONTEXT) {
|
|
251
|
+
setState = vars.sessionContext(key, seqState);
|
|
252
|
+
} else if (persist === VAR_TYPES.SESSION_DIALOGUE_CONTEXT) {
|
|
253
|
+
setState = vars.sessionContext(key, seqState, null); // same as interaction
|
|
254
|
+
} else if (persist === VAR_TYPES.DIALOG_CONTEXT) {
|
|
255
|
+
setState = vars.dialogContext(key, seqState);
|
|
256
|
+
} else {
|
|
257
|
+
setState = {
|
|
258
|
+
[key]: seqState
|
|
259
|
+
};
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
return [
|
|
263
|
+
renderMessageText(texts[seqState.i].t, data),
|
|
264
|
+
setState
|
|
265
|
+
];
|
|
266
|
+
}
|
|
267
|
+
|
|
183
268
|
/** @typedef {import('../BuildRouter').BotContext} BotContext */
|
|
184
269
|
/** @typedef {import('../Router').Resolver} Resolver */
|
|
185
270
|
|
|
@@ -192,7 +277,7 @@ function findSupportedMessages (text, features, lang = null) {
|
|
|
192
277
|
function message (params, context = {}) {
|
|
193
278
|
const {
|
|
194
279
|
// @ts-ignore
|
|
195
|
-
isLastIndex, isLastMessage, linksMap, configuration
|
|
280
|
+
isLastIndex, isLastMessage, linksMap, configuration, resolverId
|
|
196
281
|
} = context;
|
|
197
282
|
if (typeof params.text !== 'string' && !Array.isArray(params.text)) {
|
|
198
283
|
throw new Error('Message should be a text!');
|
|
@@ -225,15 +310,14 @@ function message (params, context = {}) {
|
|
|
225
310
|
data.lang
|
|
226
311
|
);
|
|
227
312
|
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
const text = textTemplate(data)
|
|
235
|
-
.trim();
|
|
313
|
+
const [text, seqState] = selectTranslation(
|
|
314
|
+
resolverId,
|
|
315
|
+
params,
|
|
316
|
+
supportedText.translations,
|
|
317
|
+
data
|
|
318
|
+
);
|
|
236
319
|
|
|
320
|
+
res.setState(seqState);
|
|
237
321
|
res.setData({ $this: text });
|
|
238
322
|
if (condition && !condition(req, res)) {
|
|
239
323
|
res.setData({ $this: null });
|
package/src/resolvers/utils.js
CHANGED
|
@@ -145,6 +145,11 @@ function getLanguageTextObjects (translations, lang = null) {
|
|
|
145
145
|
}));
|
|
146
146
|
}
|
|
147
147
|
|
|
148
|
+
function renderMessageText (fn, data) {
|
|
149
|
+
const renderer = fn === 'function' ? fn : hbs.compile(fn);
|
|
150
|
+
return renderer(data).trim();
|
|
151
|
+
}
|
|
152
|
+
|
|
148
153
|
function randomizedCompiler (text, lang) {
|
|
149
154
|
const texts = getLanguageText(text, lang);
|
|
150
155
|
|
|
@@ -307,6 +312,7 @@ module.exports = {
|
|
|
307
312
|
randomizedCompiler,
|
|
308
313
|
getText,
|
|
309
314
|
stateData,
|
|
315
|
+
renderMessageText,
|
|
310
316
|
|
|
311
317
|
ASPECT_SQUARE,
|
|
312
318
|
ASPECT_HORISONTAL,
|
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
*/
|
|
4
4
|
'use strict';
|
|
5
5
|
|
|
6
|
+
const SESSION_DIALOGUE_CONTEXT = 'sd';
|
|
7
|
+
const SESSION_CONTEXT = 's';
|
|
6
8
|
const DIALOG_CONTEXT = 'd';
|
|
7
9
|
const EXPIRES_AFTER = 't';
|
|
8
10
|
|
|
@@ -11,11 +13,27 @@ const EXPIRES_AFTER = 't';
|
|
|
11
13
|
|
|
12
14
|
const VAR_TYPES = {
|
|
13
15
|
DIALOG_CONTEXT,
|
|
14
|
-
EXPIRES_AFTER
|
|
16
|
+
EXPIRES_AFTER,
|
|
17
|
+
SESSION_DIALOGUE_CONTEXT,
|
|
18
|
+
SESSION_CONTEXT
|
|
15
19
|
};
|
|
16
20
|
|
|
21
|
+
const DIALOGUE_CONTEXT_TYPES = [DIALOG_CONTEXT, SESSION_DIALOGUE_CONTEXT];
|
|
22
|
+
|
|
17
23
|
const vars = {
|
|
18
24
|
|
|
25
|
+
/**
|
|
26
|
+
* Clears variable with it's metadata
|
|
27
|
+
*
|
|
28
|
+
* @param {string} key
|
|
29
|
+
* @returns {object}
|
|
30
|
+
*/
|
|
31
|
+
clear (key) {
|
|
32
|
+
return {
|
|
33
|
+
[key]: null
|
|
34
|
+
};
|
|
35
|
+
},
|
|
36
|
+
|
|
19
37
|
/**
|
|
20
38
|
* Sets variable, which will be removed, when user leaves the dialogue.
|
|
21
39
|
* **Variable will be available at first interaction of next dialogue.**
|
|
@@ -39,6 +57,29 @@ const vars = {
|
|
|
39
57
|
};
|
|
40
58
|
},
|
|
41
59
|
|
|
60
|
+
/**
|
|
61
|
+
* Sets variable, which will be removed, when new session is created.
|
|
62
|
+
* **When `dialoguePath` argument is provided, the variable will NOT expire,
|
|
63
|
+
* when the new session will continue in the same dialogue**
|
|
64
|
+
*
|
|
65
|
+
* @param {string} key
|
|
66
|
+
* @param {*} value
|
|
67
|
+
* @param {string|boolean} [dialoguePath] - keeps context also within a dialogue
|
|
68
|
+
* @returns {object}
|
|
69
|
+
* @example
|
|
70
|
+
* const { vars } = require('wingbot');
|
|
71
|
+
* res.setState(vars.sessionContext('myKey', 'foovalue'))
|
|
72
|
+
*/
|
|
73
|
+
sessionContext (key, value, dialoguePath = false) {
|
|
74
|
+
return {
|
|
75
|
+
[key]: value,
|
|
76
|
+
[`_~${key}`]: {
|
|
77
|
+
t: dialoguePath === false ? SESSION_CONTEXT : SESSION_DIALOGUE_CONTEXT,
|
|
78
|
+
...(dialoguePath && { p: dialoguePath })
|
|
79
|
+
}
|
|
80
|
+
};
|
|
81
|
+
},
|
|
82
|
+
|
|
42
83
|
/**
|
|
43
84
|
* Sets variable, which will be removed after specified number of conversation turonovers
|
|
44
85
|
*
|
|
@@ -98,7 +139,6 @@ function checkSetState (setState, newState) {
|
|
|
98
139
|
delete newState[metaKey]; // eslint-disable-line no-param-reassign
|
|
99
140
|
}
|
|
100
141
|
}
|
|
101
|
-
|
|
102
142
|
}
|
|
103
143
|
}
|
|
104
144
|
|
|
@@ -116,6 +156,42 @@ function isUserInteraction (req) {
|
|
|
116
156
|
|| req.isTextOrIntent());
|
|
117
157
|
}
|
|
118
158
|
|
|
159
|
+
function prepareState (state, firstInTurnover, sessionCreated) {
|
|
160
|
+
if (!sessionCreated) {
|
|
161
|
+
return;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
// set right path, when path was set
|
|
165
|
+
// eslint-disable-next-line guard-for-in
|
|
166
|
+
for (const key in state) { // eslint-disable-line no-restricted-syntax
|
|
167
|
+
const match = key.match(/^_~(.+)$/);
|
|
168
|
+
if (!match) {
|
|
169
|
+
continue;
|
|
170
|
+
}
|
|
171
|
+
const value = state[key];
|
|
172
|
+
const [, referencedKey] = match;
|
|
173
|
+
|
|
174
|
+
if (value.t === SESSION_CONTEXT) {
|
|
175
|
+
delete state[key]; // eslint-disable-line no-param-reassign
|
|
176
|
+
delete state[referencedKey]; // eslint-disable-line no-param-reassign
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
if (value.t === SESSION_DIALOGUE_CONTEXT) {
|
|
180
|
+
if (value.p === state._lastVisitedPath) {
|
|
181
|
+
// context still matches - make it just DIALOGUE_CONTEXT
|
|
182
|
+
state[key] = { // eslint-disable-line no-param-reassign
|
|
183
|
+
t: DIALOG_CONTEXT,
|
|
184
|
+
p: value.p
|
|
185
|
+
};
|
|
186
|
+
} else {
|
|
187
|
+
delete state[key]; // eslint-disable-line no-param-reassign
|
|
188
|
+
delete state[referencedKey]; // eslint-disable-line no-param-reassign
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
}
|
|
194
|
+
|
|
119
195
|
/**
|
|
120
196
|
*
|
|
121
197
|
* @private
|
|
@@ -149,7 +225,7 @@ function mergeState (previousState, req, res, senderStateUpdate, firstInTurnover
|
|
|
149
225
|
continue;
|
|
150
226
|
}
|
|
151
227
|
const value = res.newState[key];
|
|
152
|
-
if (value.t
|
|
228
|
+
if (DIALOGUE_CONTEXT_TYPES.includes(value.t) && typeof value.p === 'undefined') {
|
|
153
229
|
Object.assign(value, { p: res.newState._lastVisitedPath });
|
|
154
230
|
}
|
|
155
231
|
}
|
|
@@ -176,6 +252,15 @@ function mergeState (previousState, req, res, senderStateUpdate, firstInTurnover
|
|
|
176
252
|
continue;
|
|
177
253
|
}
|
|
178
254
|
switch (value.t) {
|
|
255
|
+
case SESSION_DIALOGUE_CONTEXT: {
|
|
256
|
+
if (!lastInTurnover || previousState._lastVisitedPath === undefined) {
|
|
257
|
+
break;
|
|
258
|
+
}
|
|
259
|
+
if (value.p === true) {
|
|
260
|
+
state[key].p = res.newState._lastVisitedPath;
|
|
261
|
+
}
|
|
262
|
+
break;
|
|
263
|
+
}
|
|
179
264
|
case DIALOG_CONTEXT: {
|
|
180
265
|
// compare state
|
|
181
266
|
|
|
@@ -190,13 +275,13 @@ function mergeState (previousState, req, res, senderStateUpdate, firstInTurnover
|
|
|
190
275
|
delete state[referencedKey];
|
|
191
276
|
}
|
|
192
277
|
|
|
193
|
-
if (lastInTurnover
|
|
194
|
-
|
|
195
|
-
|
|
278
|
+
// if (lastInTurnover
|
|
279
|
+
// && previousState._lastVisitedPath !== undefined
|
|
280
|
+
// && value.p !== res.newState._lastVisitedPath) {
|
|
196
281
|
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
}
|
|
282
|
+
// delete state[key];
|
|
283
|
+
// delete state[referencedKey];
|
|
284
|
+
// }
|
|
200
285
|
|
|
201
286
|
break;
|
|
202
287
|
}
|
|
@@ -234,6 +319,7 @@ function mergeState (previousState, req, res, senderStateUpdate, firstInTurnover
|
|
|
234
319
|
|
|
235
320
|
module.exports = {
|
|
236
321
|
VAR_TYPES,
|
|
322
|
+
prepareState,
|
|
237
323
|
mergeState,
|
|
238
324
|
vars,
|
|
239
325
|
checkSetState,
|