@teleporthq/teleport-plugin-next-workflows 0.43.61 → 0.43.63
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/__tests__/browser-speech-recognition.test.ts +625 -0
- package/__tests__/custom-event-component-scope.test.ts +143 -0
- package/__tests__/data-update-item-runtime.test.ts +39 -0
- package/__tests__/page-revalidate-node.test.ts +276 -0
- package/__tests__/payment-refund.test.ts +135 -0
- package/dist/cjs/api-route-generator.d.ts.map +1 -1
- package/dist/cjs/api-route-generator.js +1 -0
- package/dist/cjs/api-route-generator.js.map +1 -1
- package/dist/cjs/nodes/analytics/commerce-tracking.d.ts +46 -0
- package/dist/cjs/nodes/analytics/commerce-tracking.d.ts.map +1 -0
- package/dist/cjs/nodes/analytics/commerce-tracking.js +94 -0
- package/dist/cjs/nodes/analytics/commerce-tracking.js.map +1 -0
- package/dist/cjs/nodes/browser/browser-speech-recognition.d.ts +3 -0
- package/dist/cjs/nodes/browser/browser-speech-recognition.d.ts.map +1 -0
- package/dist/cjs/nodes/browser/browser-speech-recognition.js +448 -0
- package/dist/cjs/nodes/browser/browser-speech-recognition.js.map +1 -0
- package/dist/cjs/nodes/cache/page-revalidate.d.ts +3 -0
- package/dist/cjs/nodes/cache/page-revalidate.d.ts.map +1 -0
- package/dist/cjs/nodes/cache/page-revalidate.js +125 -0
- package/dist/cjs/nodes/cache/page-revalidate.js.map +1 -0
- package/dist/cjs/nodes/cart/cart-add-item.d.ts.map +1 -1
- package/dist/cjs/nodes/cart/cart-add-item.js +22 -1
- package/dist/cjs/nodes/cart/cart-add-item.js.map +1 -1
- package/dist/cjs/nodes/cart/cart-remove-item.d.ts.map +1 -1
- package/dist/cjs/nodes/cart/cart-remove-item.js +23 -1
- package/dist/cjs/nodes/cart/cart-remove-item.js.map +1 -1
- package/dist/cjs/nodes/data/data-create-item.d.ts.map +1 -1
- package/dist/cjs/nodes/data/data-create-item.js +42 -1
- package/dist/cjs/nodes/data/data-create-item.js.map +1 -1
- package/dist/cjs/nodes/data/data-update-item.d.ts.map +1 -1
- package/dist/cjs/nodes/data/data-update-item.js +38 -3
- package/dist/cjs/nodes/data/data-update-item.js.map +1 -1
- package/dist/cjs/nodes/index.d.ts.map +1 -1
- package/dist/cjs/nodes/index.js +4 -1
- package/dist/cjs/nodes/index.js.map +1 -1
- package/dist/cjs/nodes/payment/payment-refund.d.ts +3 -0
- package/dist/cjs/nodes/payment/payment-refund.d.ts.map +1 -0
- package/dist/cjs/nodes/payment/payment-refund.js +446 -0
- package/dist/cjs/nodes/payment/payment-refund.js.map +1 -0
- package/dist/cjs/secret-collector.d.ts.map +1 -1
- package/dist/cjs/secret-collector.js +3 -0
- package/dist/cjs/secret-collector.js.map +1 -1
- package/dist/cjs/tsconfig.tsbuildinfo +1 -1
- package/dist/esm/api-route-generator.d.ts.map +1 -1
- package/dist/esm/api-route-generator.js +1 -0
- package/dist/esm/api-route-generator.js.map +1 -1
- package/dist/esm/nodes/analytics/commerce-tracking.d.ts +46 -0
- package/dist/esm/nodes/analytics/commerce-tracking.d.ts.map +1 -0
- package/dist/esm/nodes/analytics/commerce-tracking.js +90 -0
- package/dist/esm/nodes/analytics/commerce-tracking.js.map +1 -0
- package/dist/esm/nodes/browser/browser-speech-recognition.d.ts +3 -0
- package/dist/esm/nodes/browser/browser-speech-recognition.d.ts.map +1 -0
- package/dist/esm/nodes/browser/browser-speech-recognition.js +445 -0
- package/dist/esm/nodes/browser/browser-speech-recognition.js.map +1 -0
- package/dist/esm/nodes/cache/page-revalidate.d.ts +3 -0
- package/dist/esm/nodes/cache/page-revalidate.d.ts.map +1 -0
- package/dist/esm/nodes/cache/page-revalidate.js +122 -0
- package/dist/esm/nodes/cache/page-revalidate.js.map +1 -0
- package/dist/esm/nodes/cart/cart-add-item.d.ts.map +1 -1
- package/dist/esm/nodes/cart/cart-add-item.js +22 -1
- package/dist/esm/nodes/cart/cart-add-item.js.map +1 -1
- package/dist/esm/nodes/cart/cart-remove-item.d.ts.map +1 -1
- package/dist/esm/nodes/cart/cart-remove-item.js +23 -1
- package/dist/esm/nodes/cart/cart-remove-item.js.map +1 -1
- package/dist/esm/nodes/data/data-create-item.d.ts.map +1 -1
- package/dist/esm/nodes/data/data-create-item.js +42 -1
- package/dist/esm/nodes/data/data-create-item.js.map +1 -1
- package/dist/esm/nodes/data/data-update-item.d.ts.map +1 -1
- package/dist/esm/nodes/data/data-update-item.js +38 -3
- package/dist/esm/nodes/data/data-update-item.js.map +1 -1
- package/dist/esm/nodes/index.d.ts.map +1 -1
- package/dist/esm/nodes/index.js +4 -1
- package/dist/esm/nodes/index.js.map +1 -1
- package/dist/esm/nodes/payment/payment-refund.d.ts +3 -0
- package/dist/esm/nodes/payment/payment-refund.d.ts.map +1 -0
- package/dist/esm/nodes/payment/payment-refund.js +443 -0
- package/dist/esm/nodes/payment/payment-refund.js.map +1 -0
- package/dist/esm/secret-collector.d.ts.map +1 -1
- package/dist/esm/secret-collector.js +3 -0
- package/dist/esm/secret-collector.js.map +1 -1
- package/dist/esm/tsconfig.tsbuildinfo +1 -1
- package/package.json +4 -4
- package/src/api-route-generator.ts +1 -0
- package/src/nodes/analytics/commerce-tracking.ts +93 -0
- package/src/nodes/browser/browser-speech-recognition.ts +474 -0
- package/src/nodes/cache/page-revalidate.ts +140 -0
- package/src/nodes/cart/cart-add-item.ts +35 -1
- package/src/nodes/cart/cart-remove-item.ts +36 -1
- package/src/nodes/data/data-create-item.ts +44 -1
- package/src/nodes/data/data-update-item.ts +39 -3
- package/src/nodes/index.ts +6 -0
- package/src/nodes/payment/payment-refund.ts +512 -0
- package/src/secret-collector.ts +3 -0
|
@@ -0,0 +1,448 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.browserSpeechRecognition = void 0;
|
|
4
|
+
const types_1 = require("../types");
|
|
5
|
+
/**
|
|
6
|
+
* A long-lived dictation session, as opposed to `browser-speech-to-text`, which
|
|
7
|
+
* awaits the FIRST phrase, resolves, and offers no way to stop.
|
|
8
|
+
*
|
|
9
|
+
* The contract this node exists for:
|
|
10
|
+
*
|
|
11
|
+
* - It RETURNS IMMEDIATELY. A workflow that awaited the transcript could not
|
|
12
|
+
* also run a second workflow to stop the microphone, and the node would hold
|
|
13
|
+
* the whole run open for as long as the visitor kept talking.
|
|
14
|
+
* - Transcripts leave through CUSTOM EVENTS (`resultEventName`), dispatched on
|
|
15
|
+
* the `workflow:custom:` channel that `event-custom-triggered` listens on. A
|
|
16
|
+
* workflow bound to that event writes the text into a field, so every
|
|
17
|
+
* app-visible effect still belongs to a workflow rather than to this handler.
|
|
18
|
+
* - The session registry on `window` — not a page state — is the authority on
|
|
19
|
+
* whether the microphone is live, so `action: "toggle"` cannot desync from
|
|
20
|
+
* reality no matter how the UI state was left.
|
|
21
|
+
*
|
|
22
|
+
* Every exit path ends in exactly one `endEventName` dispatch, including the
|
|
23
|
+
* ones that never started (unsupported browser, `start()` throwing), so the UI
|
|
24
|
+
* that turned "listening" on always has something to turn it off again.
|
|
25
|
+
*
|
|
26
|
+
* ⛔ NOTHING here is reported as an `error`. The runtime's `isFatalNodeResult`
|
|
27
|
+
* treats any non-empty `error` string as a FAILED node and aborts the rest of
|
|
28
|
+
* the workflow — which would skip the very state write that puts the button
|
|
29
|
+
* back to idle, and would fire the error branch of any workflow that has one.
|
|
30
|
+
* A browser without the API, or a visitor who declines the microphone, is a
|
|
31
|
+
* normal outcome of asking, not a failure of the workflow, so it comes back as
|
|
32
|
+
* `reason` and the caller decides what to say about it.
|
|
33
|
+
*/
|
|
34
|
+
async function browser_speech_recognition(config, _context) {
|
|
35
|
+
const REGISTRY_KEY = '__teleportSpeechSessions';
|
|
36
|
+
const DEFAULT_MAX_DURATION_MS = 120000;
|
|
37
|
+
// Chrome ends a "continuous" session after a few seconds of silence, so a
|
|
38
|
+
// dictation of any length is really a chain of restarts. The cap is what
|
|
39
|
+
// stops a microphone that can never hear anything (muted device, wrong input)
|
|
40
|
+
// from restarting forever.
|
|
41
|
+
const MAX_CONSECUTIVE_RESTARTS = 60;
|
|
42
|
+
// A run shorter than this heard nothing at all; see `onend`.
|
|
43
|
+
const MIN_USEFUL_RUN_MS = 500;
|
|
44
|
+
const MAX_RAPID_RESTARTS = 5;
|
|
45
|
+
// Errors that mean "this will not work, stop trying" rather than "nothing was
|
|
46
|
+
// said just now". `no-speech` and `aborted` are ordinary and must NOT be here.
|
|
47
|
+
const FATAL_ERRORS = ['not-allowed', 'service-not-allowed', 'audio-capture', 'bad-grammar'];
|
|
48
|
+
// ⛔ These two strings are a CONTRACT with the builder repo, where they are
|
|
49
|
+
// `SPEECH_STOP_PHRASE_REASON` / `SPEECH_SUBMIT_PHRASE_REASON` and are what a
|
|
50
|
+
// workflow gates its follow-up branch on. The handler is emitted as a
|
|
51
|
+
// standalone string in a separate repo, so it cannot import them: instead
|
|
52
|
+
// both sides pin the literal in their own tests, and either one changing the
|
|
53
|
+
// spelling alone fails there.
|
|
54
|
+
const STOP_PHRASE_REASON = 'stop-phrase';
|
|
55
|
+
const SUBMIT_PHRASE_REASON = 'submit-phrase';
|
|
56
|
+
const win = typeof window === 'undefined' ? null : window;
|
|
57
|
+
if (!win) {
|
|
58
|
+
return {
|
|
59
|
+
listening: false,
|
|
60
|
+
supported: false,
|
|
61
|
+
action: 'unchanged',
|
|
62
|
+
sessionId: '',
|
|
63
|
+
reason: 'no-window',
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
const sessions = win[REGISTRY_KEY] || (win[REGISTRY_KEY] = {});
|
|
67
|
+
const sessionId = String(config.sessionId == null || config.sessionId === '' ? 'default' : config.sessionId);
|
|
68
|
+
const requested = config.action === 'start' || config.action === 'stop' ? config.action : 'toggle';
|
|
69
|
+
const resultEventName = typeof config.resultEventName === 'string' ? config.resultEventName : '';
|
|
70
|
+
const endEventName = typeof config.endEventName === 'string' ? config.endEventName : '';
|
|
71
|
+
// What the end event reports when THIS call is the thing that stops the
|
|
72
|
+
// session. A caller that stops for a reason of its own — a spoken "send that",
|
|
73
|
+
// a navigation, a closing panel — needs the end workflow to be able to tell
|
|
74
|
+
// that apart from the visitor clicking the microphone off, and the end event
|
|
75
|
+
// is the only place both arrive.
|
|
76
|
+
const stopReason = typeof config.stopReason === 'string' && config.stopReason ? config.stopReason : 'stopped';
|
|
77
|
+
const dispatch = (eventName, detail) => {
|
|
78
|
+
if (!eventName) {
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
try {
|
|
82
|
+
win.dispatchEvent(new CustomEvent('workflow:custom:' + eventName, { detail }));
|
|
83
|
+
}
|
|
84
|
+
catch (e) {
|
|
85
|
+
/* a listener throwing must never take the session down with it */
|
|
86
|
+
}
|
|
87
|
+
};
|
|
88
|
+
const existing = sessions[sessionId];
|
|
89
|
+
const isListening = !!(existing && existing.active);
|
|
90
|
+
// ── stop ──────────────────────────────────────────────────────────────────
|
|
91
|
+
if (requested === 'stop' || (requested === 'toggle' && isListening)) {
|
|
92
|
+
if (!existing) {
|
|
93
|
+
return {
|
|
94
|
+
listening: false,
|
|
95
|
+
supported: true,
|
|
96
|
+
action: 'unchanged',
|
|
97
|
+
sessionId,
|
|
98
|
+
reason: '',
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
// Cleared BEFORE `.stop()` so the `onend` that follows finalizes instead of
|
|
102
|
+
// auto-restarting, and so a second click cannot stop the same session twice.
|
|
103
|
+
existing.active = false;
|
|
104
|
+
existing.reason = stopReason;
|
|
105
|
+
try {
|
|
106
|
+
existing.recognition.stop();
|
|
107
|
+
}
|
|
108
|
+
catch (e) {
|
|
109
|
+
// Already stopping, or never started. `onend` may therefore never fire,
|
|
110
|
+
// so finalize here instead of leaving the UI stuck on "listening".
|
|
111
|
+
if (existing.finalize) {
|
|
112
|
+
existing.finalize(stopReason, '');
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
return {
|
|
116
|
+
listening: false,
|
|
117
|
+
supported: true,
|
|
118
|
+
action: 'stopped',
|
|
119
|
+
sessionId,
|
|
120
|
+
reason: '',
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
// ── start ─────────────────────────────────────────────────────────────────
|
|
124
|
+
if (isListening) {
|
|
125
|
+
// `action: "start"` on a live session: leave it alone rather than replacing
|
|
126
|
+
// the recogniser, which would drop everything said so far.
|
|
127
|
+
return {
|
|
128
|
+
listening: true,
|
|
129
|
+
supported: true,
|
|
130
|
+
action: 'unchanged',
|
|
131
|
+
sessionId,
|
|
132
|
+
reason: '',
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
const SpeechRecognition = win.SpeechRecognition || win.webkitSpeechRecognition;
|
|
136
|
+
if (!SpeechRecognition) {
|
|
137
|
+
// Firefox, and every browser with the API behind a flag. The end event is
|
|
138
|
+
// still emitted so the caller's "listening" state is turned back off and it
|
|
139
|
+
// has a `reason` to explain the failure with.
|
|
140
|
+
dispatch(endEventName, {
|
|
141
|
+
sessionId,
|
|
142
|
+
text: typeof config.initialText === 'string' ? config.initialText : '',
|
|
143
|
+
transcript: '',
|
|
144
|
+
reason: 'unsupported',
|
|
145
|
+
error: '',
|
|
146
|
+
listening: false,
|
|
147
|
+
});
|
|
148
|
+
return {
|
|
149
|
+
listening: false,
|
|
150
|
+
supported: false,
|
|
151
|
+
action: 'unchanged',
|
|
152
|
+
sessionId,
|
|
153
|
+
reason: 'unsupported',
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
const baseText = typeof config.initialText === 'string' ? config.initialText : '';
|
|
157
|
+
const continuous = config.continuous !== false;
|
|
158
|
+
const interimResults = config.interimResults !== false;
|
|
159
|
+
const language = (typeof config.language === 'string' && config.language) ||
|
|
160
|
+
(win.document && win.document.documentElement && win.document.documentElement.lang) ||
|
|
161
|
+
'en-US';
|
|
162
|
+
const autoRestart = config.autoRestart !== false && continuous;
|
|
163
|
+
// Spoken commands. Normalised once, longest first: "stop listening" has to
|
|
164
|
+
// win over "stop", or the longer spelling leaves "listening" in the field.
|
|
165
|
+
const toPhraseList = (value) => (Array.isArray(value) ? value : [])
|
|
166
|
+
.map((entry) => String(entry == null ? '' : entry)
|
|
167
|
+
.toLowerCase()
|
|
168
|
+
.trim())
|
|
169
|
+
.filter(function (entry) {
|
|
170
|
+
return entry !== '';
|
|
171
|
+
})
|
|
172
|
+
.sort(function (a, b) {
|
|
173
|
+
return b.length - a.length;
|
|
174
|
+
});
|
|
175
|
+
const stopPhrases = toPhraseList(config.stopPhrases);
|
|
176
|
+
const submitPhrases = toPhraseList(config.submitPhrases);
|
|
177
|
+
const maxDurationMs = typeof config.maxDurationMs === 'number' && config.maxDurationMs > 0
|
|
178
|
+
? config.maxDurationMs
|
|
179
|
+
: DEFAULT_MAX_DURATION_MS;
|
|
180
|
+
const session = {
|
|
181
|
+
active: true,
|
|
182
|
+
startedAt: 0,
|
|
183
|
+
rapidRestarts: 0,
|
|
184
|
+
baseText,
|
|
185
|
+
// Finals from recogniser runs that have already ended. Kept apart from the
|
|
186
|
+
// current run's finals because a restarted recogniser reports its own
|
|
187
|
+
// results from index 0 again, so the two cannot share one accumulator.
|
|
188
|
+
committedText: '',
|
|
189
|
+
currentFinalText: '',
|
|
190
|
+
lastEmitted: null,
|
|
191
|
+
restarts: 0,
|
|
192
|
+
reason: 'ended',
|
|
193
|
+
matchedPhrase: '',
|
|
194
|
+
error: '',
|
|
195
|
+
finished: false,
|
|
196
|
+
recognition: null,
|
|
197
|
+
timer: null,
|
|
198
|
+
finalize: null,
|
|
199
|
+
};
|
|
200
|
+
sessions[sessionId] = session;
|
|
201
|
+
// Every seam between two pieces of text needs the same rule: without it,
|
|
202
|
+
// "hello" typed then "there" spoken comes back as "hellothere".
|
|
203
|
+
const join = (head, tail) => {
|
|
204
|
+
if (!head) {
|
|
205
|
+
return tail;
|
|
206
|
+
}
|
|
207
|
+
if (!tail) {
|
|
208
|
+
return head;
|
|
209
|
+
}
|
|
210
|
+
return /\s$/.test(head) ? head + tail : head + ' ' + tail;
|
|
211
|
+
};
|
|
212
|
+
/** Everything recognised so far in this session, across restarts. */
|
|
213
|
+
const spokenSoFar = () => join(session.committedText, session.currentFinalText);
|
|
214
|
+
/** What the target field should now contain. */
|
|
215
|
+
const compose = (spoken) => join(session.baseText, spoken);
|
|
216
|
+
// ── spoken commands ───────────────────────────────────────────────────────
|
|
217
|
+
// A command is the LAST thing said, so matching is anchored to the end of the
|
|
218
|
+
// text and to a word boundary — "enclose" is not "close", and "how do I
|
|
219
|
+
// submit a return" is not a submit. Trailing punctuation is the recogniser's,
|
|
220
|
+
// never the visitor's: "send it." and "send it" are one instruction.
|
|
221
|
+
const trimCommandTail = (value) => value.replace(/[\s.,!?;:]+$/, '');
|
|
222
|
+
// ⛔ The MESSAGE keeps its own punctuation. Only the separator between it and
|
|
223
|
+
// the command goes — the pause comma the recogniser writes for "what time do
|
|
224
|
+
// you open, send it". Trimming the same set would turn a dictated question
|
|
225
|
+
// into a statement.
|
|
226
|
+
const trimSeparator = (value) => value.replace(/[\s,;:]+$/, '');
|
|
227
|
+
const matchPhraseAtEnd = (text, phrases) => {
|
|
228
|
+
const trimmed = trimCommandTail(text);
|
|
229
|
+
const lower = trimmed.toLowerCase();
|
|
230
|
+
for (let i = 0; i < phrases.length; i += 1) {
|
|
231
|
+
const phrase = phrases[i];
|
|
232
|
+
if (!phrase || lower.length < phrase.length) {
|
|
233
|
+
continue;
|
|
234
|
+
}
|
|
235
|
+
if (lower.slice(lower.length - phrase.length) !== phrase) {
|
|
236
|
+
continue;
|
|
237
|
+
}
|
|
238
|
+
const head = trimmed.slice(0, trimmed.length - phrase.length);
|
|
239
|
+
if (head !== '' && !/\s$/.test(head)) {
|
|
240
|
+
continue;
|
|
241
|
+
}
|
|
242
|
+
return { phrase, rest: trimSeparator(head) };
|
|
243
|
+
}
|
|
244
|
+
return null;
|
|
245
|
+
};
|
|
246
|
+
/**
|
|
247
|
+
* What the field should show, and what the visitor asked for.
|
|
248
|
+
*
|
|
249
|
+
* Stripping runs on EVERY update so the command word is never visible, and is
|
|
250
|
+
* self-correcting: an interim that revises itself puts the word back on the
|
|
251
|
+
* next one. Only a settled phrase ACTS, which is what stops a half-spoken
|
|
252
|
+
* sentence from firing.
|
|
253
|
+
*/
|
|
254
|
+
const readCommand = (text, isFinal) => {
|
|
255
|
+
if (stopPhrases.length === 0 && submitPhrases.length === 0) {
|
|
256
|
+
return { text, action: '', phrase: '' };
|
|
257
|
+
}
|
|
258
|
+
let hit = matchPhraseAtEnd(text, submitPhrases);
|
|
259
|
+
let action = hit ? 'submit' : '';
|
|
260
|
+
if (!hit) {
|
|
261
|
+
hit = matchPhraseAtEnd(text, stopPhrases);
|
|
262
|
+
action = hit ? 'stop' : '';
|
|
263
|
+
}
|
|
264
|
+
if (!hit) {
|
|
265
|
+
return { text, action: '', phrase: '' };
|
|
266
|
+
}
|
|
267
|
+
// Nothing left to act on is a plain stop, never an empty submission.
|
|
268
|
+
if (action === 'submit' && hit.rest.trim() === '') {
|
|
269
|
+
action = 'stop';
|
|
270
|
+
}
|
|
271
|
+
return { text: hit.rest, action: isFinal ? action : '', phrase: hit.phrase };
|
|
272
|
+
};
|
|
273
|
+
const finalize = (reason, error, matchedPhrase) => {
|
|
274
|
+
if (session.finished) {
|
|
275
|
+
return;
|
|
276
|
+
}
|
|
277
|
+
session.finished = true;
|
|
278
|
+
session.active = false;
|
|
279
|
+
if (session.timer) {
|
|
280
|
+
clearTimeout(session.timer);
|
|
281
|
+
session.timer = null;
|
|
282
|
+
}
|
|
283
|
+
// ⛔ A session that has been REPLACED must die quietly. `onend` arrives a
|
|
284
|
+
// task after `.stop()`, so a click landing in that gap starts a fresh
|
|
285
|
+
// session under the same name — and the old one's end event would then turn
|
|
286
|
+
// the UI off while the new microphone is live.
|
|
287
|
+
const isCurrent = sessions[sessionId] === session;
|
|
288
|
+
if (!isCurrent) {
|
|
289
|
+
return;
|
|
290
|
+
}
|
|
291
|
+
delete sessions[sessionId];
|
|
292
|
+
// The command word is cut out here too, so the end event's text is the same
|
|
293
|
+
// thing the field was left showing.
|
|
294
|
+
const spoken = readCommand(spokenSoFar(), true);
|
|
295
|
+
dispatch(endEventName, {
|
|
296
|
+
sessionId,
|
|
297
|
+
text: compose(spoken.text),
|
|
298
|
+
transcript: spoken.text,
|
|
299
|
+
reason,
|
|
300
|
+
error,
|
|
301
|
+
matchedPhrase: matchedPhrase || '',
|
|
302
|
+
listening: false,
|
|
303
|
+
});
|
|
304
|
+
};
|
|
305
|
+
session.finalize = finalize;
|
|
306
|
+
const recognition = new SpeechRecognition();
|
|
307
|
+
session.recognition = recognition;
|
|
308
|
+
recognition.lang = language;
|
|
309
|
+
recognition.continuous = continuous;
|
|
310
|
+
recognition.interimResults = interimResults;
|
|
311
|
+
if (typeof config.maxAlternatives === 'number' && config.maxAlternatives > 0) {
|
|
312
|
+
recognition.maxAlternatives = config.maxAlternatives;
|
|
313
|
+
}
|
|
314
|
+
recognition.onresult = (event) => {
|
|
315
|
+
// ⛔ REBUILT from the whole result list, never appended from
|
|
316
|
+
// `event.resultIndex`. An engine is free to re-report a result that is
|
|
317
|
+
// already final (Chrome does when a later phrase revises an earlier one),
|
|
318
|
+
// and an append would then say the same sentence twice. Rebuilding is
|
|
319
|
+
// idempotent whatever the engine re-sends.
|
|
320
|
+
let currentFinal = '';
|
|
321
|
+
let interim = '';
|
|
322
|
+
const results = event.results || [];
|
|
323
|
+
for (let i = 0; i < results.length; i += 1) {
|
|
324
|
+
const result = results[i];
|
|
325
|
+
const alternative = result && result[0];
|
|
326
|
+
const text = alternative && alternative.transcript ? String(alternative.transcript).trim() : '';
|
|
327
|
+
if (result && result.isFinal) {
|
|
328
|
+
currentFinal = join(currentFinal, text);
|
|
329
|
+
}
|
|
330
|
+
else {
|
|
331
|
+
interim = join(interim, text);
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
session.currentFinalText = currentFinal;
|
|
335
|
+
const isFinal = !interim;
|
|
336
|
+
const spoken = readCommand(join(spokenSoFar(), interim), isFinal);
|
|
337
|
+
const composed = compose(spoken.text);
|
|
338
|
+
// The API re-emits an unchanged interim result several times a second;
|
|
339
|
+
// without this guard each one would run the consuming workflow again.
|
|
340
|
+
//
|
|
341
|
+
// ⛔ Finality is part of the key. The last interim of a phrase almost always
|
|
342
|
+
// has the SAME text as the final that follows it, so keying on the text
|
|
343
|
+
// alone swallowed the final event entirely — and a consumer that only acts
|
|
344
|
+
// on settled speech (a spoken command, a submit) would then never fire.
|
|
345
|
+
const emissionKey = composed + '\u0000' + (isFinal ? '1' : '0');
|
|
346
|
+
if (emissionKey !== session.lastEmitted) {
|
|
347
|
+
session.lastEmitted = emissionKey;
|
|
348
|
+
dispatch(resultEventName, {
|
|
349
|
+
sessionId,
|
|
350
|
+
text: composed,
|
|
351
|
+
transcript: spoken.text,
|
|
352
|
+
isFinal,
|
|
353
|
+
listening: true,
|
|
354
|
+
});
|
|
355
|
+
}
|
|
356
|
+
if (!spoken.action) {
|
|
357
|
+
return;
|
|
358
|
+
}
|
|
359
|
+
// A spoken command ends the session itself. The result event above went out
|
|
360
|
+
// first and carries the text with the command already cut out, so whatever
|
|
361
|
+
// writes it into the field has the final value before the end event lands.
|
|
362
|
+
session.active = false;
|
|
363
|
+
session.reason = spoken.action === 'submit' ? SUBMIT_PHRASE_REASON : STOP_PHRASE_REASON;
|
|
364
|
+
session.matchedPhrase = spoken.phrase;
|
|
365
|
+
try {
|
|
366
|
+
recognition.stop();
|
|
367
|
+
}
|
|
368
|
+
catch (e) {
|
|
369
|
+
finalize(session.reason, '', spoken.phrase);
|
|
370
|
+
}
|
|
371
|
+
};
|
|
372
|
+
recognition.onerror = (event) => {
|
|
373
|
+
const code = (event && event.error) || 'unknown';
|
|
374
|
+
session.error = code;
|
|
375
|
+
if (FATAL_ERRORS.indexOf(code) >= 0) {
|
|
376
|
+
session.active = false;
|
|
377
|
+
session.reason = code;
|
|
378
|
+
}
|
|
379
|
+
};
|
|
380
|
+
recognition.onend = () => {
|
|
381
|
+
// A run that ended almost as soon as it began never listened to anything —
|
|
382
|
+
// no microphone, or the speech service unreachable. Restarting those as fast
|
|
383
|
+
// as the browser allows is a tight loop, so they get a much shorter leash
|
|
384
|
+
// than the ordinary silence-timeout restarts they are counted apart from.
|
|
385
|
+
const ranFor = Date.now() - session.startedAt;
|
|
386
|
+
session.rapidRestarts = ranFor < MIN_USEFUL_RUN_MS ? session.rapidRestarts + 1 : 0;
|
|
387
|
+
const canRestart = session.active &&
|
|
388
|
+
autoRestart &&
|
|
389
|
+
session.restarts < MAX_CONSECUTIVE_RESTARTS &&
|
|
390
|
+
session.rapidRestarts < MAX_RAPID_RESTARTS &&
|
|
391
|
+
!(win.document && win.document.hidden);
|
|
392
|
+
if (!canRestart) {
|
|
393
|
+
finalize(session.active ? 'ended' : session.reason, session.error, session.matchedPhrase);
|
|
394
|
+
return;
|
|
395
|
+
}
|
|
396
|
+
// Bank this run's finals before the recogniser starts numbering from 0
|
|
397
|
+
// again, and drop the error that ended it — `no-speech` from a pause must
|
|
398
|
+
// not be reported as the reason the whole session eventually stopped.
|
|
399
|
+
session.committedText = spokenSoFar();
|
|
400
|
+
session.currentFinalText = '';
|
|
401
|
+
session.error = '';
|
|
402
|
+
session.restarts += 1;
|
|
403
|
+
session.startedAt = Date.now();
|
|
404
|
+
try {
|
|
405
|
+
recognition.start();
|
|
406
|
+
}
|
|
407
|
+
catch (e) {
|
|
408
|
+
finalize('ended', session.error);
|
|
409
|
+
}
|
|
410
|
+
};
|
|
411
|
+
session.startedAt = Date.now();
|
|
412
|
+
try {
|
|
413
|
+
recognition.start();
|
|
414
|
+
}
|
|
415
|
+
catch (e) {
|
|
416
|
+
// `InvalidStateError` from a recogniser the browser still considers running.
|
|
417
|
+
finalize('start-failed', e.message || 'start-failed');
|
|
418
|
+
return {
|
|
419
|
+
listening: false,
|
|
420
|
+
supported: true,
|
|
421
|
+
action: 'unchanged',
|
|
422
|
+
sessionId,
|
|
423
|
+
reason: 'start-failed',
|
|
424
|
+
};
|
|
425
|
+
}
|
|
426
|
+
session.timer = setTimeout(() => {
|
|
427
|
+
if (!session.active) {
|
|
428
|
+
return;
|
|
429
|
+
}
|
|
430
|
+
session.active = false;
|
|
431
|
+
session.reason = 'timeout';
|
|
432
|
+
try {
|
|
433
|
+
recognition.stop();
|
|
434
|
+
}
|
|
435
|
+
catch (e) {
|
|
436
|
+
finalize('timeout', '');
|
|
437
|
+
}
|
|
438
|
+
}, maxDurationMs);
|
|
439
|
+
return { listening: true, supported: true, action: 'started', sessionId, reason: '' };
|
|
440
|
+
}
|
|
441
|
+
exports.browserSpeechRecognition = {
|
|
442
|
+
nodeType: 'browser-speech-recognition',
|
|
443
|
+
executionEnv: 'client',
|
|
444
|
+
generateHandler() {
|
|
445
|
+
return (0, types_1.handlerToString)(browser_speech_recognition);
|
|
446
|
+
},
|
|
447
|
+
};
|
|
448
|
+
//# sourceMappingURL=browser-speech-recognition.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"browser-speech-recognition.js","sourceRoot":"","sources":["../../../../src/nodes/browser/browser-speech-recognition.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"page-revalidate.d.ts","sourceRoot":"","sources":["../../../../src/nodes/cache/page-revalidate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAmB,MAAM,UAAU,CAAA;AAqIhE,eAAO,MAAM,cAAc,EAAE,oBAM5B,CAAA"}
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.pageRevalidate = void 0;
|
|
4
|
+
const types_1 = require("../types");
|
|
5
|
+
/**
|
|
6
|
+
* Rebuilds statically generated pages on the published site.
|
|
7
|
+
*
|
|
8
|
+
* This is the OTHER cache a published project serves from. `cache-invalidate`
|
|
9
|
+
* clears the data-API cache; a page built by `getStaticProps` keeps serving the
|
|
10
|
+
* HTML it was built with regardless, until its ISR window expires. So an admin
|
|
11
|
+
* who creates, edits or deletes a row watches the public URL stay wrong for the
|
|
12
|
+
* length of that window. Calling `res.revalidate(path)` re-runs `getStaticProps`
|
|
13
|
+
* for that path immediately.
|
|
14
|
+
*
|
|
15
|
+
* SERVER-classified deliberately, for the same two reasons as
|
|
16
|
+
* `cache-invalidate`: `res.revalidate` only exists inside a server route, and
|
|
17
|
+
* being server-side lands it in the SAME segment as the write it follows, so
|
|
18
|
+
* adding it to a CRUD workflow costs no extra round trip.
|
|
19
|
+
*
|
|
20
|
+
* It reaches the rebuild through the app's own `POST /api/tq-revalidate` rather
|
|
21
|
+
* than by importing anything: node handlers ship as runtime source and are
|
|
22
|
+
* re-bundled by webpack, which rewrites `require(` — so an internal HTTP call is
|
|
23
|
+
* the sanctioned way for a handler to reach server-side machinery, and it is
|
|
24
|
+
* also the only way to get at a `res` object with `revalidate` on it.
|
|
25
|
+
*
|
|
26
|
+
* ⛔ Never mark this node fire-and-forget. Its workflows navigate or refresh a
|
|
27
|
+
* page immediately afterwards, and that reload routinely wins the race against
|
|
28
|
+
* an unawaited rebuild — leaving the visitor looking at the stale page this was
|
|
29
|
+
* meant to replace.
|
|
30
|
+
*
|
|
31
|
+
* ⛔ It also must NEVER return `{ success: false }` or a string `error`. The
|
|
32
|
+
* runtime treats both as FATAL and halts the workflow (`isFatalNodeResult`), so
|
|
33
|
+
* a page that could not be rebuilt would abort an admin's save AFTER the row was
|
|
34
|
+
* already written — no success toast, no navigation, and an error for an action
|
|
35
|
+
* that worked. Outcomes are reported as `revalidated` plus a `warning`, and the
|
|
36
|
+
* page's own ISR window remains the safety net.
|
|
37
|
+
*/
|
|
38
|
+
async function page_revalidate(config, context) {
|
|
39
|
+
const configured = Array.isArray(config.paths)
|
|
40
|
+
? config.paths
|
|
41
|
+
: config.paths === undefined || config.paths === null
|
|
42
|
+
? []
|
|
43
|
+
: [config.paths];
|
|
44
|
+
// One level of flattening: a step that revalidates several rows at once (a
|
|
45
|
+
// bulk delete, say) resolves ONE reference to an array of slugs rather than
|
|
46
|
+
// configuring a path per row.
|
|
47
|
+
const flattened = [];
|
|
48
|
+
for (let i = 0; i < configured.length; i++) {
|
|
49
|
+
const entry = configured[i];
|
|
50
|
+
if (Array.isArray(entry)) {
|
|
51
|
+
for (let j = 0; j < entry.length; j++) {
|
|
52
|
+
flattened.push(entry[j]);
|
|
53
|
+
}
|
|
54
|
+
continue;
|
|
55
|
+
}
|
|
56
|
+
flattened.push(entry);
|
|
57
|
+
}
|
|
58
|
+
const paths = [];
|
|
59
|
+
for (let i = 0; i < flattened.length; i++) {
|
|
60
|
+
const raw = flattened[i];
|
|
61
|
+
if (raw === undefined || raw === null || typeof raw === 'object') {
|
|
62
|
+
continue;
|
|
63
|
+
}
|
|
64
|
+
const trimmed = String(raw).trim();
|
|
65
|
+
if (!trimmed) {
|
|
66
|
+
continue;
|
|
67
|
+
}
|
|
68
|
+
// `res.revalidate` only accepts a site-root-relative path, and a step whose
|
|
69
|
+
// path came from a database column often holds the bare slug.
|
|
70
|
+
const normalized = trimmed.charAt(0) === '/' ? trimmed : '/' + trimmed;
|
|
71
|
+
if (paths.indexOf(normalized) === -1) {
|
|
72
|
+
paths.push(normalized);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
if (!paths.length) {
|
|
76
|
+
return {
|
|
77
|
+
revalidated: [],
|
|
78
|
+
warning: 'No page paths were configured on this step.',
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
const baseUrl = context.__baseUrl || '';
|
|
82
|
+
const __internalHeaders = context.__internalHeaders || {};
|
|
83
|
+
const __env = globalThis.process && globalThis.process.env;
|
|
84
|
+
const secret = __env ? __env.TQ_CACHE_SECRET : '';
|
|
85
|
+
if (!secret) {
|
|
86
|
+
// Reported rather than thrown: the write this follows already succeeded, and
|
|
87
|
+
// the page still refreshes on its own revalidate window.
|
|
88
|
+
return {
|
|
89
|
+
revalidated: [],
|
|
90
|
+
warning: 'TQ_CACHE_SECRET is not configured, so published pages will refresh on their own schedule.',
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
try {
|
|
94
|
+
const response = await fetch(baseUrl + '/api/tq-revalidate', {
|
|
95
|
+
method: 'POST',
|
|
96
|
+
headers: Object.assign({ 'Content-Type': 'application/json', 'x-tq-cache-secret': secret }, __internalHeaders),
|
|
97
|
+
body: JSON.stringify({ paths }),
|
|
98
|
+
});
|
|
99
|
+
const data = await response.json();
|
|
100
|
+
if (!response.ok || !data.ok) {
|
|
101
|
+
const warning = data.error || 'The published pages could not be refreshed; they will refresh on their own.';
|
|
102
|
+
return { revalidated: [], warning };
|
|
103
|
+
}
|
|
104
|
+
const revalidated = Array.isArray(data.revalidated) ? data.revalidated : [];
|
|
105
|
+
const failed = Array.isArray(data.failed) ? data.failed : [];
|
|
106
|
+
if (failed.length) {
|
|
107
|
+
return {
|
|
108
|
+
revalidated,
|
|
109
|
+
warning: 'Some pages could not be refreshed and will refresh on their own: ' + failed.join(', '),
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
return { revalidated };
|
|
113
|
+
}
|
|
114
|
+
catch (err) {
|
|
115
|
+
return { revalidated: [], warning: err.message };
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
exports.pageRevalidate = {
|
|
119
|
+
nodeType: 'page-revalidate',
|
|
120
|
+
executionEnv: 'server',
|
|
121
|
+
generateHandler() {
|
|
122
|
+
return (0, types_1.handlerToString)(page_revalidate);
|
|
123
|
+
},
|
|
124
|
+
};
|
|
125
|
+
//# sourceMappingURL=page-revalidate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"page-revalidate.js","sourceRoot":"","sources":["../../../../src/nodes/cache/page-revalidate.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cart-add-item.d.ts","sourceRoot":"","sources":["../../../../src/nodes/cart/cart-add-item.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAmB,MAAM,UAAU,CAAA;
|
|
1
|
+
{"version":3,"file":"cart-add-item.d.ts","sourceRoot":"","sources":["../../../../src/nodes/cart/cart-add-item.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAmB,MAAM,UAAU,CAAA;AAmJhE,eAAO,MAAM,WAAW,EAAE,oBAWzB,CAAA"}
|