annyang 2.6.1 → 3.0.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/LICENSE +1 -1
- package/README.md +55 -31
- package/dist/annyang.cjs +354 -0
- package/dist/annyang.cjs.map +1 -0
- package/dist/annyang.d.cts +288 -0
- package/dist/annyang.d.ts +288 -0
- package/dist/annyang.iife.min.js +1 -0
- package/dist/annyang.js +296 -670
- package/dist/annyang.js.map +1 -1
- package/package.json +54 -36
- package/.editorconfig +0 -13
- package/.eslintrc.json +0 -34
- package/.gitattributes +0 -1
- package/.github/ISSUE_TEMPLATE.md +0 -32
- package/.github/PULL_REQUEST_TEMPLATE.md +0 -29
- package/.jshintrc +0 -31
- package/.travis.yml +0 -20
- package/CONTRIBUTING.md +0 -75
- package/Gruntfile.js +0 -144
- package/bower.json +0 -25
- package/demo/css/main.css +0 -152
- package/demo/css/main.min.css +0 -1
- package/demo/images/flickr.png +0 -0
- package/demo/images/footer_background.jpg +0 -0
- package/demo/images/icon_js.png +0 -0
- package/demo/images/icon_speech.png +0 -0
- package/demo/images/icon_user.png +0 -0
- package/demo/images/mini_icon_say.png +0 -0
- package/demo/images/palette.png +0 -0
- package/demo/images/tpscover.jpg +0 -0
- package/demo/index.html +0 -225
- package/demo/vendor/css/default.css +0 -135
- package/demo/vendor/css/github.css +0 -127
- package/demo/vendor/css/tomorrow.css +0 -49
- package/demo/vendor/html/github-btn.html +0 -243
- package/demo/vendor/js/highlight.pack.js +0 -1
- package/dist/annyang.min.js +0 -12
- package/docs/FAQ.md +0 -223
- package/docs/README.md +0 -336
- package/require.js +0 -36
- package/sites/README.md +0 -6
- package/sites/facebook.js +0 -123
- package/sites/facebook.min.js +0 -17
- package/sites/geektime.js +0 -108
- package/sites/geektime.min.js +0 -17
- package/src/annyang.js +0 -680
- package/test/SpecRunner.html +0 -41
- package/test/init_corti.js +0 -1
- package/test/spec/.jshintrc +0 -40
- package/test/spec/BasicSpec.js +0 -1616
- package/test/spec/IssuesSpec.js +0 -41
- package/test/vendor/corti.js +0 -202
- package/yarn.lock +0 -4190
package/dist/annyang.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/annyang.js"],"names":["root","factory","define","amd","annyang","module","exports","window","undefined","SpeechRecognition","webkitSpeechRecognition","mozSpeechRecognition","msSpeechRecognition","oSpeechRecognition","commandsList","recognition","callbacks","start","error","end","soundstart","result","resultMatch","resultNoMatch","errorNetwork","errorPermissionBlocked","errorPermissionDenied","autoRestart","lastStartedAt","autoRestartCount","debugState","debugStyle","pauseListening","isListening","optionalParam","optionalRegex","namedParam","splatParam","escapeRegExp","commandToRegExp","command","replace","match","optional","RegExp","invokeCallbacks","args","forEach","callback","apply","context","isInitialized","logMessage","text","extraParameters","indexOf","console","log","initIfNeeded","init","registerCommand","originalPhrase","push","parseResults","results","commandText","i","length","trim","j","l","currentCommand","exec","parameters","slice","commands","resetCommands","abort","maxAlternatives","continuous","location","protocol","lang","onstart","onsoundstart","onerror","event","Date","getTime","onend","timeSinceLastStart","setTimeout","paused","onresult","SpeechRecognitionResult","resultIndex","k","transcript","addCommands","options","e","message","pause","resume","debug","newState","setLanguage","language","cb","phrase","hasOwnProperty","regexp","source","removeCommands","commandsToRemove","Array","isArray","filter","addCallback","type","removeCallback","compareWithCallbackParameter","callbackType","getSpeechRecognizer","trigger","sentences"],"mappings":"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","file":"annyang.js","sourcesContent":["//! annyang\n//! version : 2.6.1\n//! author : Tal Ater @TalAter\n//! license : MIT\n//! https://www.TalAter.com/annyang/\n(function (root, factory) {\n 'use strict';\n if (typeof define === 'function' && define.amd) { // AMD + global\n define([], function () {\n return (root.annyang = factory(root));\n });\n } else if (typeof module === 'object' && module.exports) { // CommonJS\n module.exports = factory(root);\n } else { // Browser globals\n root.annyang = factory(root);\n }\n}(typeof window !== 'undefined' ? window : this, function (root, undefined) {\n 'use strict';\n\n /**\n * # Quick Tutorial, Intro and Demos\n *\n * The quickest way to get started is to visit the [annyang homepage](https://www.talater.com/annyang/).\n *\n * For a more in-depth look at annyang, read on.\n *\n * # API Reference\n */\n\n var annyang;\n\n // Get the SpeechRecognition object, while handling browser prefixes\n var SpeechRecognition = root.SpeechRecognition ||\n root.webkitSpeechRecognition ||\n root.mozSpeechRecognition ||\n root.msSpeechRecognition ||\n root.oSpeechRecognition;\n\n // Check browser support\n // This is done as early as possible, to make it as fast as possible for unsupported browsers\n if (!SpeechRecognition) {\n return null;\n }\n\n var commandsList = [];\n var recognition;\n var callbacks = { start: [], error: [], end: [], soundstart: [], result: [], resultMatch: [], resultNoMatch: [], errorNetwork: [], errorPermissionBlocked: [], errorPermissionDenied: [] };\n var autoRestart;\n var lastStartedAt = 0;\n var autoRestartCount = 0;\n var debugState = false;\n var debugStyle = 'font-weight: bold; color: #00f;';\n var pauseListening = false;\n var isListening = false;\n\n // The command matching code is a modified version of Backbone.Router by Jeremy Ashkenas, under the MIT license.\n var optionalParam = /\\s*\\((.*?)\\)\\s*/g;\n var optionalRegex = /(\\(\\?:[^)]+\\))\\?/g;\n var namedParam = /(\\(\\?)?:\\w+/g;\n var splatParam = /\\*\\w+/g;\n var escapeRegExp = /[\\-{}\\[\\]+?.,\\\\\\^$|#]/g;\n var commandToRegExp = function(command) {\n command = command.replace(escapeRegExp, '\\\\$&')\n .replace(optionalParam, '(?:$1)?')\n .replace(namedParam, function(match, optional) {\n return optional ? match : '([^\\\\s]+)';\n })\n .replace(splatParam, '(.*?)')\n .replace(optionalRegex, '\\\\s*$1?\\\\s*');\n return new RegExp('^' + command + '$', 'i');\n };\n\n // This method receives an array of callbacks to iterate over, and invokes each of them\n var invokeCallbacks = function(callbacks, ...args) {\n callbacks.forEach(function(callback) {\n callback.callback.apply(callback.context, args);\n });\n };\n\n var isInitialized = function() {\n return recognition !== undefined;\n };\n\n // method for logging in developer console when debug mode is on\n var logMessage = function(text, extraParameters) {\n if (text.indexOf('%c') === -1 && !extraParameters) {\n console.log(text);\n } else {\n console.log(text, extraParameters || debugStyle);\n }\n };\n\n var initIfNeeded = function() {\n if (!isInitialized()) {\n annyang.init({}, false);\n }\n };\n\n var registerCommand = function(command, callback, originalPhrase) {\n commandsList.push({ command, callback, originalPhrase });\n if (debugState) {\n logMessage('Command successfully loaded: %c'+originalPhrase, debugStyle);\n }\n };\n\n var parseResults = function(results) {\n invokeCallbacks(callbacks.result, results);\n var commandText;\n // go over each of the 5 results and alternative results received (we've set maxAlternatives to 5 above)\n for (let i = 0; i<results.length; i++) {\n // the text recognized\n commandText = results[i].trim();\n if (debugState) {\n logMessage('Speech recognized: %c'+commandText, debugStyle);\n }\n\n // try and match recognized text to one of the commands on the list\n for (let j = 0, l = commandsList.length; j < l; j++) {\n var currentCommand = commandsList[j];\n var result = currentCommand.command.exec(commandText);\n if (result) {\n var parameters = result.slice(1);\n if (debugState) {\n logMessage('command matched: %c'+currentCommand.originalPhrase, debugStyle);\n if (parameters.length) {\n logMessage('with parameters', parameters);\n }\n }\n // execute the matched command\n currentCommand.callback.apply(this, parameters);\n invokeCallbacks(callbacks.resultMatch, commandText, currentCommand.originalPhrase, results);\n return;\n }\n }\n }\n invokeCallbacks(callbacks.resultNoMatch, results);\n };\n\n annyang = {\n\n /**\n * Initialize annyang with a list of commands to recognize.\n *\n * #### Examples:\n * ````javascript\n * var commands = {'hello :name': helloFunction};\n * var commands2 = {'hi': helloFunction};\n *\n * // initialize annyang, overwriting any previously added commands\n * annyang.init(commands, true);\n * // adds an additional command without removing the previous commands\n * annyang.init(commands2, false);\n * ````\n * As of v1.1.0 it is no longer required to call init(). Just start() listening whenever you want, and addCommands() whenever, and as often as you like.\n *\n * @param {Object} commands - Commands that annyang should listen to\n * @param {boolean} [resetCommands=true] - Remove all commands before initializing?\n * @method init\n * @deprecated\n * @see [Commands Object](#commands-object)\n */\n init: function(commands, resetCommands = true) {\n // Abort previous instances of recognition already running\n if (recognition && recognition.abort) {\n recognition.abort();\n }\n\n // initiate SpeechRecognition\n recognition = new SpeechRecognition();\n\n // Set the max number of alternative transcripts to try and match with a command\n recognition.maxAlternatives = 5;\n\n // In HTTPS, turn off continuous mode for faster results.\n // In HTTP, turn on continuous mode for much slower results, but no repeating security notices\n recognition.continuous = root.location.protocol === 'http:';\n\n // Sets the language to the default 'en-US'. This can be changed with annyang.setLanguage()\n recognition.lang = 'en-US';\n\n recognition.onstart = function() {\n isListening = true;\n invokeCallbacks(callbacks.start);\n };\n\n recognition.onsoundstart = function() {\n invokeCallbacks(callbacks.soundstart);\n };\n\n recognition.onerror = function(event) {\n invokeCallbacks(callbacks.error, event);\n switch (event.error) {\n case 'network':\n invokeCallbacks(callbacks.errorNetwork, event);\n break;\n case 'not-allowed':\n case 'service-not-allowed':\n // if permission to use the mic is denied, turn off auto-restart\n autoRestart = false;\n // determine if permission was denied by user or automatically.\n if (new Date().getTime()-lastStartedAt < 200) {\n invokeCallbacks(callbacks.errorPermissionBlocked, event);\n } else {\n invokeCallbacks(callbacks.errorPermissionDenied, event);\n }\n break;\n }\n };\n\n recognition.onend = function() {\n isListening = false;\n invokeCallbacks(callbacks.end);\n // annyang will auto restart if it is closed automatically and not by user action.\n if (autoRestart) {\n // play nicely with the browser, and never restart annyang automatically more than once per second\n var timeSinceLastStart = new Date().getTime()-lastStartedAt;\n autoRestartCount += 1;\n if (autoRestartCount % 10 === 0) {\n if (debugState) {\n logMessage('Speech Recognition is repeatedly stopping and starting. See http://is.gd/annyang_restarts for tips.');\n }\n }\n if (timeSinceLastStart < 1000) {\n setTimeout(function() {\n annyang.start({ paused: pauseListening });\n }, 1000-timeSinceLastStart);\n } else {\n annyang.start({ paused: pauseListening });\n }\n }\n };\n\n recognition.onresult = function(event) {\n if(pauseListening) {\n if (debugState) {\n logMessage('Speech heard, but annyang is paused');\n }\n return false;\n }\n\n // Map the results to an array\n var SpeechRecognitionResult = event.results[event.resultIndex];\n var results = [];\n for (let k = 0; k<SpeechRecognitionResult.length; k++) {\n results[k] = SpeechRecognitionResult[k].transcript;\n }\n\n parseResults(results);\n };\n\n // build commands list\n if (resetCommands) {\n commandsList = [];\n }\n if (commands.length) {\n this.addCommands(commands);\n }\n },\n\n /**\n * Start listening.\n * It's a good idea to call this after adding some commands first, but not mandatory.\n *\n * Receives an optional options object which supports the following options:\n *\n * - `autoRestart` (boolean, default: true) Should annyang restart itself if it is closed indirectly, because of silence or window conflicts?\n * - `continuous` (boolean) Allow forcing continuous mode on or off. Annyang is pretty smart about this, so only set this if you know what you're doing.\n * - `paused` (boolean, default: true) Start annyang in paused mode.\n *\n * #### Examples:\n * ````javascript\n * // Start listening, don't restart automatically\n * annyang.start({ autoRestart: false });\n * // Start listening, don't restart automatically, stop recognition after first phrase recognized\n * annyang.start({ autoRestart: false, continuous: false });\n * ````\n * @param {Object} [options] - Optional options.\n * @method start\n */\n start: function(options) {\n initIfNeeded();\n options = options || {};\n if (options.paused !== undefined) {\n pauseListening = !!options.paused;\n } else {\n pauseListening = false;\n }\n if (options.autoRestart !== undefined) {\n autoRestart = !!options.autoRestart;\n } else {\n autoRestart = true;\n }\n if (options.continuous !== undefined) {\n recognition.continuous = !!options.continuous;\n }\n\n lastStartedAt = new Date().getTime();\n try {\n recognition.start();\n } catch(e) {\n if (debugState) {\n logMessage(e.message);\n }\n }\n },\n\n /**\n * Stop listening, and turn off mic.\n *\n * Alternatively, to only temporarily pause annyang responding to commands without stopping the SpeechRecognition engine or closing the mic, use pause() instead.\n * @see [pause()](#pause)\n *\n * @method abort\n */\n abort: function() {\n autoRestart = false;\n autoRestartCount = 0;\n if (isInitialized()) {\n recognition.abort();\n }\n },\n\n /**\n * Pause listening. annyang will stop responding to commands (until the resume or start methods are called), without turning off the browser's SpeechRecognition engine or the mic.\n *\n * Alternatively, to stop the SpeechRecognition engine and close the mic, use abort() instead.\n * @see [abort()](#abort)\n *\n * @method pause\n */\n pause: function() {\n pauseListening = true;\n },\n\n /**\n * Resumes listening and restores command callback execution when a result matches.\n * If SpeechRecognition was aborted (stopped), start it.\n *\n * @method resume\n */\n resume: function() {\n annyang.start();\n },\n\n /**\n * Turn on output of debug messages to the console. Ugly, but super-handy!\n *\n * @param {boolean} [newState=true] - Turn on/off debug messages\n * @method debug\n */\n debug: function(newState = true) {\n debugState = !!newState;\n },\n\n /**\n * Set the language the user will speak in. If this method is not called, defaults to 'en-US'.\n *\n * @param {String} language - The language (locale)\n * @method setLanguage\n * @see [Languages](https://github.com/TalAter/annyang/blob/master/docs/FAQ.md#what-languages-are-supported)\n */\n setLanguage: function(language) {\n initIfNeeded();\n recognition.lang = language;\n },\n\n /**\n * Add commands that annyang will respond to. Similar in syntax to init(), but doesn't remove existing commands.\n *\n * #### Examples:\n * ````javascript\n * var commands = {'hello :name': helloFunction, 'howdy': helloFunction};\n * var commands2 = {'hi': helloFunction};\n *\n * annyang.addCommands(commands);\n * annyang.addCommands(commands2);\n * // annyang will now listen to all three commands\n * ````\n *\n * @param {Object} commands - Commands that annyang should listen to\n * @method addCommands\n * @see [Commands Object](#commands-object)\n */\n addCommands: function(commands) {\n var cb;\n\n initIfNeeded();\n\n for (let phrase in commands) {\n if (commands.hasOwnProperty(phrase)) {\n cb = root[commands[phrase]] || commands[phrase];\n if (typeof cb === 'function') {\n // convert command to regex then register the command\n registerCommand(commandToRegExp(phrase), cb, phrase);\n } else if (typeof cb === 'object' && cb.regexp instanceof RegExp) {\n // register the command\n registerCommand(new RegExp(cb.regexp.source, 'i'), cb.callback, phrase);\n } else {\n if (debugState) {\n logMessage('Can not register command: %c'+phrase, debugStyle);\n }\n continue;\n }\n }\n }\n },\n\n /**\n * Remove existing commands. Called with a single phrase, array of phrases, or methodically. Pass no params to remove all commands.\n *\n * #### Examples:\n * ````javascript\n * var commands = {'hello': helloFunction, 'howdy': helloFunction, 'hi': helloFunction};\n *\n * // Remove all existing commands\n * annyang.removeCommands();\n *\n * // Add some commands\n * annyang.addCommands(commands);\n *\n * // Don't respond to hello\n * annyang.removeCommands('hello');\n *\n * // Don't respond to howdy or hi\n * annyang.removeCommands(['howdy', 'hi']);\n * ````\n * @param {String|Array|Undefined} [commandsToRemove] - Commands to remove\n * @method removeCommands\n */\n removeCommands: function(commandsToRemove) {\n if (commandsToRemove === undefined) {\n commandsList = [];\n } else {\n commandsToRemove = Array.isArray(commandsToRemove) ? commandsToRemove : [commandsToRemove];\n commandsList = commandsList.filter(command => {\n for (let i = 0; i<commandsToRemove.length; i++) {\n if (commandsToRemove[i] === command.originalPhrase) {\n return false;\n }\n }\n return true;\n });\n }\n },\n\n /**\n * Add a callback function to be called in case one of the following events happens:\n *\n * * `start` - Fired as soon as the browser's Speech Recognition engine starts listening\n * * `soundstart` - Fired as soon as any sound (possibly speech) has been detected.\n * This will fire once per Speech Recognition starting. See https://is.gd/annyang_sound_start\n * * `error` - Fired when the browser's Speech Recogntion engine returns an error, this generic error callback will be followed by more accurate error callbacks (both will fire if both are defined)\n * Callback function will be called with the error event as the first argument\n * * `errorNetwork` - Fired when Speech Recognition fails because of a network error\n * Callback function will be called with the error event as the first argument\n * * `errorPermissionBlocked` - Fired when the browser blocks the permission request to use Speech Recognition.\n * Callback function will be called with the error event as the first argument\n * * `errorPermissionDenied` - Fired when the user blocks the permission request to use Speech Recognition.\n * Callback function will be called with the error event as the first argument\n * * `end` - Fired when the browser's Speech Recognition engine stops\n * * `result` - Fired as soon as some speech was identified. This generic callback will be followed by either the `resultMatch` or `resultNoMatch` callbacks.\n * Callback functions for to this event will be called with an array of possible phrases the user said as the first argument\n * * `resultMatch` - Fired when annyang was able to match between what the user said and a registered command\n * Callback functions for this event will be called with three arguments in the following order:\n * * The phrase the user said that matched a command\n * * The command that was matched\n * * An array of possible alternative phrases the user might have said\n * * `resultNoMatch` - Fired when what the user said didn't match any of the registered commands.\n * Callback functions for this event will be called with an array of possible phrases the user might've said as the first argument\n *\n * #### Examples:\n * ````javascript\n * annyang.addCallback('error', function() {\n * $('.myErrorText').text('There was an error!');\n * });\n *\n * annyang.addCallback('resultMatch', function(userSaid, commandText, phrases) {\n * console.log(userSaid); // sample output: 'hello'\n * console.log(commandText); // sample output: 'hello (there)'\n * console.log(phrases); // sample output: ['hello', 'halo', 'yellow', 'polo', 'hello kitty']\n * });\n *\n * // pass local context to a global function called notConnected\n * annyang.addCallback('errorNetwork', notConnected, this);\n * ````\n * @param {String} type - Name of event that will trigger this callback\n * @param {Function} callback - The function to call when event is triggered\n * @param {Object} [context] - Optional context for the callback function\n * @method addCallback\n */\n addCallback: function(type, callback, context) {\n var cb = root[callback] || callback;\n if (typeof cb === 'function' && callbacks[type] !== undefined) {\n callbacks[type].push({callback: cb, context: context || this});\n }\n },\n\n /**\n * Remove callbacks from events.\n *\n * - Pass an event name and a callback command to remove that callback command from that event type.\n * - Pass just an event name to remove all callback commands from that event type.\n * - Pass undefined as event name and a callback command to remove that callback command from all event types.\n * - Pass no params to remove all callback commands from all event types.\n *\n * #### Examples:\n * ````javascript\n * annyang.addCallback('start', myFunction1);\n * annyang.addCallback('start', myFunction2);\n * annyang.addCallback('end', myFunction1);\n * annyang.addCallback('end', myFunction2);\n *\n * // Remove all callbacks from all events:\n * annyang.removeCallback();\n *\n * // Remove all callbacks attached to end event:\n * annyang.removeCallback('end');\n *\n * // Remove myFunction2 from being called on start:\n * annyang.removeCallback('start', myFunction2);\n *\n * // Remove myFunction1 from being called on all events:\n * annyang.removeCallback(undefined, myFunction1);\n * ````\n *\n * @param type Name of event type to remove callback from\n * @param callback The callback function to remove\n * @returns undefined\n * @method removeCallback\n */\n removeCallback: function(type, callback) {\n var compareWithCallbackParameter = function(cb) {\n return cb.callback !== callback;\n };\n // Go over each callback type in callbacks store object\n for (let callbackType in callbacks) {\n if (callbacks.hasOwnProperty(callbackType)) {\n // if this is the type user asked to delete, or he asked to delete all, go ahead.\n if (type === undefined || type === callbackType) {\n // If user asked to delete all callbacks in this type or all types\n if (callback === undefined) {\n callbacks[callbackType] = [];\n } else {\n // Remove all matching callbacks\n callbacks[callbackType] = callbacks[callbackType].filter(compareWithCallbackParameter);\n }\n }\n }\n }\n },\n\n /**\n * Returns true if speech recognition is currently on.\n * Returns false if speech recognition is off or annyang is paused.\n *\n * @return boolean true = SpeechRecognition is on and annyang is listening\n * @method isListening\n */\n isListening: function() {\n return isListening && !pauseListening;\n },\n\n /**\n * Returns the instance of the browser's SpeechRecognition object used by annyang.\n * Useful in case you want direct access to the browser's Speech Recognition engine.\n *\n * @returns SpeechRecognition The browser's Speech Recognizer currently used by annyang\n * @method getSpeechRecognizer\n */\n getSpeechRecognizer: function() {\n return recognition;\n },\n\n /**\n * Simulate speech being recognized. This will trigger the same events and behavior as when the Speech Recognition\n * detects speech.\n *\n * Can accept either a string containing a single sentence, or an array containing multiple sentences to be checked\n * in order until one of them matches a command (similar to the way Speech Recognition Alternatives are parsed)\n *\n * #### Examples:\n * ````javascript\n * annyang.trigger('Time for some thrilling heroics');\n * annyang.trigger(\n * ['Time for some thrilling heroics', 'Time for some thrilling aerobics']\n * );\n * ````\n *\n * @param string|array sentences A sentence as a string or an array of strings of possible sentences\n * @returns undefined\n * @method trigger\n */\n trigger: function(sentences) {\n if(!annyang.isListening()) {\n if (debugState) {\n if (!isListening) {\n logMessage('Cannot trigger while annyang is aborted');\n } else {\n logMessage('Speech heard, but annyang is paused');\n }\n }\n return;\n }\n\n if (!Array.isArray(sentences)) {\n sentences = [sentences];\n }\n\n parseResults(sentences);\n }\n };\n\n return annyang;\n\n}));\n\n/**\n * # Good to Know\n *\n * ## Commands Object\n *\n * Both the [init()]() and addCommands() methods receive a `commands` object.\n *\n * annyang understands commands with `named variables`, `splats`, and `optional words`.\n *\n * * Use `named variables` for one word arguments in your command.\n * * Use `splats` to capture multi-word text at the end of your command (greedy).\n * * Use `optional words` or phrases to define a part of the command as optional.\n *\n * #### Examples:\n * ````html\n * <script>\n * var commands = {\n * // annyang will capture anything after a splat (*) and pass it to the function.\n * // e.g. saying \"Show me Batman and Robin\" will call showFlickr('Batman and Robin');\n * 'show me *tag': showFlickr,\n *\n * // A named variable is a one word variable, that can fit anywhere in your command.\n * // e.g. saying \"calculate October stats\" will call calculateStats('October');\n * 'calculate :month stats': calculateStats,\n *\n * // By defining a part of the following command as optional, annyang will respond\n * // to both: \"say hello to my little friend\" as well as \"say hello friend\"\n * 'say hello (to my little) friend': greeting\n * };\n *\n * var showFlickr = function(tag) {\n * var url = 'http://api.flickr.com/services/rest/?tags='+tag;\n * $.getJSON(url);\n * }\n *\n * var calculateStats = function(month) {\n * $('#stats').text('Statistics for '+month);\n * }\n *\n * var greeting = function() {\n * $('#greeting').text('Hello!');\n * }\n * </script>\n * ````\n *\n * ### Using Regular Expressions in commands\n * For advanced commands, you can pass a regular expression object, instead of\n * a simple string command.\n *\n * This is done by passing an object containing two properties: `regexp`, and\n * `callback` instead of the function.\n *\n * #### Examples:\n * ````javascript\n * var calculateFunction = function(month) { console.log(month); }\n * var commands = {\n * // This example will accept any word as the \"month\"\n * 'calculate :month stats': calculateFunction,\n * // This example will only accept months which are at the start of a quarter\n * 'calculate :quarter stats': {'regexp': /^calculate (January|April|July|October) stats$/, 'callback': calculateFunction}\n * }\n ````\n *\n */\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/annyang.ts"],"sourcesContent":["const MIN_RESTART_INTERVAL_MS = 1000;\nconst RESTART_WARNING_INTERVAL = 10;\n\nlet recognition: SpeechRecognition;\nlet listening: boolean = false;\nlet autoRestart: boolean = true;\nlet debugState: boolean = false;\nconst debugStyle: string = 'font-weight: bold; color: #00f;';\n\nexport interface CallbackMap {\n start: () => void;\n end: () => void;\n soundstart: () => void;\n result: (phrases: string[]) => void;\n resultMatch: (userSaid: string, commandText: string, phrases: string[]) => void;\n resultNoMatch: (phrases: string[]) => void;\n error: (event: SpeechRecognitionErrorEvent) => void;\n errorNetwork: (event: SpeechRecognitionErrorEvent) => void;\n errorPermissionBlocked: (event: SpeechRecognitionErrorEvent) => void;\n errorPermissionDenied: (event: SpeechRecognitionErrorEvent) => void;\n}\n\nexport type CallbackType = keyof CallbackMap;\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype AnyFunction = (...args: any[]) => void;\n\ninterface StoredCallback {\n callback: AnyFunction;\n context: object | undefined;\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nconst commandsList: Map<string, { command: RegExp; callback: (...args: any[]) => void }> = new Map();\nconst callbacks: Map<CallbackType, StoredCallback[]> = new Map([\n ['start', []],\n ['error', []],\n ['end', []],\n ['soundstart', []],\n ['result', []],\n ['resultMatch', []],\n ['resultNoMatch', []],\n ['errorNetwork', []],\n ['errorPermissionBlocked', []],\n ['errorPermissionDenied', []],\n]);\nlet lastStartedAt: number = 0;\nlet autoRestartCount: number = 0;\nlet pauseListening: boolean = false;\n\n// The command matching code is a modified version of Backbone.Router by Jeremy Ashkenas, under the MIT license.\nconst optionalParam = /\\s*\\((.*?)\\)\\s*/g;\nconst optionalRegex = /(\\(\\?:[^)]+\\))\\?/g;\nconst namedParam = /(\\(\\?)?:\\w+/g;\nconst splatParam = /\\*\\w+/g;\nconst escapeRegExp = /[-{}[\\]+?.,\\\\^$|#]/g;\nconst commandToRegExp = (command: string) => {\n const parsedCommand = command\n .replace(escapeRegExp, '\\\\$&')\n .replace(optionalParam, '(?:$1)?')\n .replace(namedParam, (match, optional) => {\n return optional ? match : '([^\\\\s]+)';\n })\n .replace(splatParam, '(.*?)')\n .replace(optionalRegex, '\\\\s*$1?\\\\s*');\n return new RegExp(`^${parsedCommand}$`, 'i');\n};\n\n// Get the SpeechRecognition object, accounting for possible browser prefixes\nconst getSpeechRecognition = () => globalThis.SpeechRecognition || globalThis.webkitSpeechRecognition;\n\n// Check if annyang is already initialized\nconst isInitialized = () => {\n return recognition !== undefined;\n};\n\n// Method for logging to the console when debug mode is on\nconst logMessage = (text: string, extraParameters?: string | string[]) => {\n if (debugState) {\n if (text.indexOf('%c') === -1 && !extraParameters) {\n console.log(text);\n } else {\n console.log(text, extraParameters || debugStyle);\n }\n }\n};\n\n// Add a command to the commands list\nconst registerCommand = (command: RegExp, callback: AnyFunction, originalPhrase: string) => {\n commandsList.set(originalPhrase, { command, callback });\n logMessage(`Command successfully loaded: %c${originalPhrase}`, debugStyle);\n};\n\n// This method receives an array of callbacks and invokes each of them\nconst invokeCallbacks = (callbacksArr: StoredCallback[] = [], ...args: unknown[]) => {\n callbacksArr.forEach(cb => {\n cb.callback.apply(cb.context, args);\n });\n};\n\n// Initialize annyang\nconst init = () => {\n if (!getSpeechRecognition()) {\n return;\n }\n\n // Abort previous instances of recognition already running\n if (recognition && recognition.abort) {\n recognition.abort();\n }\n\n // initiate SpeechRecognition\n recognition = new (getSpeechRecognition())();\n\n // Set the max number of alternative transcripts to try and match with a command\n recognition.maxAlternatives = 5;\n\n // In HTTPS, turn off continuous mode for faster results.\n // In HTTP, turn on continuous mode for much slower results, but no repeating security notices\n recognition.continuous = globalThis.location.protocol === 'http:';\n\n // Sets the language to the default 'en-US'. This can be changed with annyang.setLanguage()\n recognition.lang = 'en-US';\n\n recognition.onstart = () => {\n listening = true;\n invokeCallbacks(callbacks.get('start'));\n };\n\n recognition.onsoundstart = () => {\n invokeCallbacks(callbacks.get('soundstart'));\n };\n\n recognition.onerror = event => {\n invokeCallbacks(callbacks.get('error'), event);\n switch (event.error) {\n case 'network':\n invokeCallbacks(callbacks.get('errorNetwork'), event);\n break;\n case 'not-allowed':\n case 'service-not-allowed':\n // if permission to use the mic is denied, turn off auto-restart\n autoRestart = false;\n // determine if permission was denied by user or automatically.\n if (new Date().getTime() - lastStartedAt < 200) {\n invokeCallbacks(callbacks.get('errorPermissionBlocked'), event);\n } else {\n invokeCallbacks(callbacks.get('errorPermissionDenied'), event);\n }\n break;\n default:\n break;\n }\n };\n\n recognition.onend = () => {\n listening = false;\n invokeCallbacks(callbacks.get('end'));\n // annyang will auto restart if it is closed automatically and not by user action.\n if (autoRestart) {\n // play nicely with the browser, and never restart annyang automatically more than once per second\n const timeSinceLastStart = new Date().getTime() - lastStartedAt;\n autoRestartCount += 1;\n if (autoRestartCount % RESTART_WARNING_INTERVAL === 0) {\n logMessage(\n 'Speech Recognition is repeatedly stopping and starting. See http://is.gd/annyang_restarts for tips.'\n );\n }\n if (timeSinceLastStart < MIN_RESTART_INTERVAL_MS) {\n setTimeout(() => {\n start({ paused: pauseListening });\n }, MIN_RESTART_INTERVAL_MS - timeSinceLastStart);\n } else {\n start({ paused: pauseListening });\n }\n }\n };\n\n recognition.onresult = (event: SpeechRecognitionEvent) => {\n if (pauseListening) {\n logMessage('Speech heard, but annyang is paused');\n return;\n }\n\n // Map the results to an array\n const SpeechRecognitionResults = event.results[event.resultIndex];\n const results = Array.from(SpeechRecognitionResults, result => result.transcript);\n parseResults(results);\n };\n};\n\n// If annyang isn't initialized, initialize it\nconst initIfNeeded = () => {\n if (!isInitialized()) {\n init();\n }\n};\n\nconst parseResults = (recognitionResults: string[]) => {\n invokeCallbacks(callbacks.get('result'), recognitionResults);\n\n // Log all recognition alternatives for debugging, regardless of match\n for (const rawText of recognitionResults) {\n logMessage(`Speech recognized: %c${rawText.trim()}`, debugStyle);\n }\n\n // Try to match each alternative to a command\n for (const rawText of recognitionResults) {\n const commandText = rawText.trim();\n for (const [originalPhrase, currentCommand] of commandsList) {\n const matchedCommand = currentCommand.command.exec(commandText);\n if (matchedCommand) {\n const parameters = matchedCommand.slice(1);\n logMessage(`command matched: %c${originalPhrase}`, debugStyle);\n if (parameters.length) {\n logMessage('with parameters', parameters);\n }\n currentCommand.callback(...parameters);\n invokeCallbacks(callbacks.get('resultMatch'), commandText, originalPhrase, recognitionResults);\n return;\n }\n }\n }\n invokeCallbacks(callbacks.get('resultNoMatch'), recognitionResults);\n};\n\n/**\n * Is SpeechRecognition supported in this environment?\n *\n * @returns {boolean} true if SpeechRecognition is supported by the browser\n */\nconst isSpeechRecognitionSupported = () => !!getSpeechRecognition();\n\nexport type CommandCallback = (...args: string[]) => void;\n\nexport interface CommandsList {\n [key: string]:\n | CommandCallback\n | {\n regexp: RegExp;\n callback: CommandCallback;\n };\n}\n\n/**\n * Add commands that annyang will respond to.\n * By default this will add to the existing commands. Pass `true` as the second parameter to remove all existing commands first.\n *\n * #### Examples:\n * ````javascript\n * const commands1 = {'hello :name': helloFunction, 'howdy': helloFunction};\n * const commands2 = {'hi': helloFunction};\n *\n * annyang.addCommands(commands1);\n * annyang.addCommands(commands2);\n * // annyang will now listen for all three commands defined in commands1 and commands2\n *\n * annyang.addCommands(commands2, true);\n * // annyang will now only listen for the command in commands2\n * ````\n *\n * @param {Object} commands - Commands that annyang should listen for\n * @param {boolean} [resetCommands=false] - Remove all existing commands before adding new commands? * @see [Commands Object](#commands-object)\n */\nconst addCommands = (commands: CommandsList, resetCommands = false) => {\n if (resetCommands) {\n commandsList.clear();\n }\n\n for (const phrase of Object.keys(commands)) {\n const cb = commands[phrase];\n\n if (typeof cb === 'function') {\n // convert command to regex then register the command\n registerCommand(commandToRegExp(phrase), cb, phrase);\n } else if (typeof cb === 'object' && cb.regexp instanceof RegExp) {\n // register the command\n registerCommand(new RegExp(cb.regexp.source, 'i'), cb.callback, phrase);\n } else {\n logMessage(`Can not register command: %c${phrase}`, debugStyle);\n }\n }\n};\n\n/**\n * Remove existing commands. Called with a single phrase, an array of phrases, or with no params to remove all commands.\n *\n * #### Examples:\n * ````javascript\n * const commands = {'hello': helloFunction, 'howdy': helloFunction, 'hi': helloFunction};\n *\n * // Remove all existing commands\n * annyang.removeCommands();\n *\n * // Add some commands\n * annyang.addCommands(commands);\n *\n * // Don't respond to hello\n * annyang.removeCommands('hello');\n *\n * // Don't respond to howdy or hi\n * annyang.removeCommands(['howdy', 'hi']);\n * ````\n * @param {string|string[]|undefined} [commandsToRemove] - Commands to remove\n */\nconst removeCommands = (commandsToRemove?: string | string[] | undefined) => {\n if (commandsToRemove === undefined) {\n commandsList.clear();\n } else {\n const commandsToRemoveArray = Array.isArray(commandsToRemove) ? commandsToRemove : [commandsToRemove];\n commandsToRemoveArray.forEach(command => commandsList.delete(command));\n }\n};\n\nexport interface StartOptions {\n autoRestart?: boolean;\n continuous?: boolean;\n paused?: boolean;\n}\n\n/**\n * Start listening.\n * It's a good idea to call this after adding some commands first (but not mandatory)\n *\n * Receives an optional options object which supports the following options:\n *\n * - `autoRestart` (boolean) Should annyang restart itself if it is closed indirectly (e.g. because of silence or window conflicts)?\n * - `continuous` (boolean) Allow forcing continuous mode on or off. annyang is pretty smart about this, so only set this if you know what you're doing.\n * - `paused` (boolean) Start annyang in paused mode.\n *\n * #### Examples:\n * ````javascript\n * // Start listening, don't restart automatically\n * annyang.start({ autoRestart: false });\n * // Start listening, don't restart automatically, stop recognition after first phrase recognized\n * annyang.start({ autoRestart: false, continuous: false });\n * ````\n * @param {Object} [options] - Optional options.\n */\nconst start = (options: StartOptions = {}) => {\n if (!isSpeechRecognitionSupported()) {\n return;\n }\n initIfNeeded();\n pauseListening = !!options.paused;\n if (options.autoRestart !== undefined) {\n autoRestart = !!options.autoRestart;\n } else {\n autoRestart = true;\n }\n if (options.continuous !== undefined) {\n recognition.continuous = !!options.continuous;\n }\n\n lastStartedAt = new Date().getTime();\n try {\n recognition.start();\n } catch (e: unknown) {\n logMessage(e instanceof Error ? e.message : String(e));\n }\n};\n\n/**\n * Stop listening and turn off the mic.\n *\n * Alternatively, to only temporarily pause annyang responding to commands without stopping the SpeechRecognition engine or closing the mic, use pause() instead.\n * @see [pause()](#pause)\n */\nconst abort = () => {\n autoRestart = false;\n autoRestartCount = 0;\n if (isInitialized()) {\n recognition.abort();\n }\n};\n\n/**\n * Pause listening. annyang will stop responding to commands (until the resume or start methods are called), without turning off the browser's SpeechRecognition engine or the mic.\n *\n * Alternatively, to stop the SpeechRecognition engine and close the mic, use abort() instead.\n * @see [abort()](#abort)\n */\nconst pause = () => {\n pauseListening = true;\n};\n\n/**\n * Resumes listening and restore command callback execution when a command is matched.\n * If SpeechRecognition was aborted (stopped), start it.\n */\nconst resume = () => {\n start();\n};\n\n/**\n * Add a callback function to be called in case one of the following events happens:\n *\n * * `start` - Fired as soon as the browser's Speech Recognition engine starts listening.\n *\n * * `soundstart` - Fired as soon as any sound (possibly speech) has been detected.\n *\n * This will fire once per Speech Recognition starting. See https://is.gd/annyang_sound_start.\n *\n * * `error` - Fired when the browser's Speech Recognition engine returns an error, this generic error callback will be followed by more accurate error callbacks (both will fire if both are defined).\n *\n * The Callback function will be called with the error event as the first argument.\n *\n * * `errorNetwork` - Fired when Speech Recognition fails because of a network error.\n *\n * The Callback function will be called with the error event as the first argument.\n *\n * * `errorPermissionBlocked` - Fired when the browser blocks the permission request to use Speech Recognition.\n *\n * The Callback function will be called with the error event as the first argument.\n *\n * * `errorPermissionDenied` - Fired when the user blocks the permission request to use Speech Recognition.\n *\n * The Callback function will be called with the error event as the first argument.\n *\n * * `end` - Fired when the browser's Speech Recognition engine stops.\n *\n * * `result` - Fired as soon as some speech was identified. This generic callback will be followed by either the `resultMatch` or `resultNoMatch` callbacks.\n *\n * The Callback functions for this event will be called with an array of possible phrases the user said as the first argument.\n *\n * * `resultMatch` - Fired when annyang was able to match between what the user said and a registered command.\n *\n * The Callback functions for this event will be called with three arguments in the following order:\n *\n * * The phrase the user said that matched a command.\n * * The command that was matched.\n * * An array of possible alternative phrases the user might have said.\n *\n * * `resultNoMatch` - Fired when what the user said didn't match any of the registered commands.\n *\n * Callback functions for this event will be called with an array of possible phrases the user might have said as the first argument.\n *\n * #### Examples:\n * ````javascript\n * annyang.addCallback('resultMatch', (userSaid, commandText, phrases) => {\n * console.log(userSaid); // sample output: 'hello'\n * console.log(commandText); // sample output: 'hello (there)'\n * console.log(phrases); // sample output: ['hello', 'halo', 'yellow', 'polo', 'hello kitty']\n * });\n *\n * // Returns an unsubscribe function\n * const unsubscribe = annyang.addCallback('error', () => {\n * console.log('There was an error!');\n * });\n * unsubscribe(); // removes the callback\n * ````\n * @param {string} type - Name of event that will trigger this callback\n * @param {function} callback - The function to call when event is triggered\n * @param {Object} [context] - Optional context for the callback function\n * @returns {function} A function that removes this callback when called\n */\nconst addCallback = <T extends CallbackType>(\n type: T,\n callback: CallbackMap[T],\n context: object | undefined = undefined\n): (() => void) => {\n const callbacksOfType = callbacks.get(type);\n if (typeof callback === 'function' && callbacksOfType) {\n const entry: StoredCallback = {\n callback: callback as AnyFunction,\n context,\n };\n callbacksOfType.push(entry);\n return () => {\n const arr = callbacks.get(type);\n if (arr) {\n const idx = arr.indexOf(entry);\n if (idx !== -1) arr.splice(idx, 1);\n }\n };\n }\n return () => {};\n};\n\n/**\n * Remove callbacks from events.\n *\n * - Pass an event name and a callback command to remove that callback command from that event type.\n * - Pass just an event name to remove all callback commands from that event type.\n * - Pass undefined as event name and a callback command to remove that callback command from all event types.\n * - Pass no params to remove all callback commands from all event types.\n *\n * #### Examples:\n * ````javascript\n * annyang.addCallback('start', myFunction1);\n * annyang.addCallback('start', myFunction2);\n * annyang.addCallback('end', myFunction1);\n * annyang.addCallback('end', myFunction2);\n *\n * // Remove all callbacks from all events:\n * annyang.removeCallback();\n *\n * // Remove all callbacks attached to end event:\n * annyang.removeCallback('end');\n *\n * // Remove myFunction2 from being called on start:\n * annyang.removeCallback('start', myFunction2);\n *\n * // Remove myFunction1 from being called on all events:\n * annyang.removeCallback(undefined, myFunction1);\n * ````\n *\n * @param type Name of event type to remove callback from\n * @param callback The callback function to remove\n * @returns undefined\n */\nconst removeCallback = (type?: CallbackType, callback?: CallbackMap[CallbackType]) => {\n callbacks.forEach((callbacksArray, callbackType) => {\n if (type === undefined || type === callbackType) {\n if (callback === undefined) {\n callbacks.get(callbackType)!.length = 0;\n } else {\n callbacks.set(\n callbackType,\n callbacksArray.filter(cb => cb.callback !== callback)\n );\n }\n }\n });\n};\n\n/**\n * Returns true if speech recognition is currently on.\n * Returns false if speech recognition is off or annyang is paused.\n *\n * @returns true if SpeechRecognition is on and annyang is not paused\n */\nconst isListening = () => {\n return listening && !pauseListening;\n};\n\nexport type AnnyangState = 'idle' | 'listening' | 'paused';\n\n/**\n * Returns the current state of annyang.\n *\n * @returns {'idle' | 'listening' | 'paused'} The current state\n */\nconst getState = (): AnnyangState => {\n if (!listening) return 'idle';\n if (pauseListening) return 'paused';\n return 'listening';\n};\n\n/**\n * Set the language the user will speak in. If this method is not called, annyang defaults to 'en-US'.\n *\n * @param {string} language - The language (locale)\n * @see [Languages](https://github.com/TalAter/annyang/blob/master/docs/FAQ.md#what-languages-are-supported)\n */\nconst setLanguage = (language: string): void => {\n if (!isSpeechRecognitionSupported()) {\n return;\n }\n initIfNeeded();\n recognition.lang = language;\n};\n\n/**\n * Turn on the output of debug messages to the console.\n *\n * @param {boolean} [newState=true] - Turn debug messages on or off\n */\nconst debug = (newState: boolean = true): void => {\n debugState = !!newState;\n};\n\n/**\n * Match text against registered commands and fire the corresponding callbacks.\n * Works independently of the speech recognition engine — does not require `start()`, and works even in\n * environments where SpeechRecognition is not supported.\n *\n * Can accept either a string containing a single sentence or an array containing multiple sentences to be checked\n * in order until one of them matches a command (similar to the way Speech Recognition Alternatives are parsed)\n *\n * #### Examples:\n * ````javascript\n * annyang.trigger('Time for some thrilling heroics');\n * annyang.trigger(\n * ['Time for some thrilling heroics', 'Time for some thrilling aerobics']\n * );\n * ````\n *\n * @param sentences - A sentence as a string or an array of strings of possible sentences\n */\nconst trigger = (sentences: string | string[] = []) => {\n parseResults(Array.isArray(sentences) ? sentences : [sentences]);\n};\n\n/**\n * Returns the instance of the browser's SpeechRecognition object used by annyang.\n * Useful in case you want direct access to the browser's Speech Recognition engine.\n *\n * @returns SpeechRecognition The browser's Speech Recognizer instance currently used by annyang\n */\nconst getSpeechRecognizer = (): SpeechRecognition | undefined => {\n return recognition;\n};\n\n/**\n * @deprecated annyang no longer requires manual initialization. It initializes automatically on `start()` or `addCommands()`. Remove any calls to `init()`.\n */\nconst initDeprecated = () => {\n console.warn(\n 'annyang.init() is deprecated and no longer needed. ' +\n 'annyang initializes automatically on start() or addCommands(). Remove this call.'\n );\n};\n\nexport {\n abort,\n addCallback,\n addCommands,\n debug,\n getSpeechRecognizer,\n getState,\n initDeprecated as init,\n isListening,\n isSpeechRecognitionSupported,\n pause,\n removeCallback,\n removeCommands,\n resume,\n setLanguage,\n start,\n trigger,\n};\n\nconst annyang = {\n isSpeechRecognitionSupported,\n addCommands,\n removeCommands,\n start,\n abort,\n pause,\n resume,\n addCallback,\n removeCallback,\n isListening,\n setLanguage,\n trigger,\n debug,\n getSpeechRecognizer,\n getState,\n init: initDeprecated,\n get state() {\n return getState();\n },\n} as const;\n\nexport default annyang;\n"],"mappings":"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","names":[]}
|
package/package.json
CHANGED
|
@@ -1,48 +1,66 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "annyang",
|
|
3
|
-
"version": "
|
|
4
|
-
"description": "A
|
|
5
|
-
"keywords": [
|
|
6
|
-
"annyang",
|
|
7
|
-
"annyang.js",
|
|
8
|
-
"recognition",
|
|
9
|
-
"speech",
|
|
10
|
-
"speechrecognition",
|
|
11
|
-
"voice",
|
|
12
|
-
"webkitspeechrecognition"
|
|
13
|
-
],
|
|
3
|
+
"version": "3.0.0",
|
|
4
|
+
"description": "A JavaScript library for adding voice commands to your site, using speech recognition",
|
|
5
|
+
"keywords": ["speech", "recognition", "voice", "commands", "speechrecognition"],
|
|
14
6
|
"homepage": "https://www.talater.com/annyang/",
|
|
15
7
|
"bugs": {
|
|
16
8
|
"url": "https://github.com/TalAter/annyang/issues"
|
|
17
9
|
},
|
|
18
|
-
"license": "MIT",
|
|
19
|
-
"author": "Tal Ater <tal@talater.com> (https://www.talater.com/)",
|
|
20
|
-
"main": "dist/annyang.min.js",
|
|
21
10
|
"repository": {
|
|
22
11
|
"type": "git",
|
|
23
|
-
"url": "https://github.com/TalAter/annyang.git"
|
|
12
|
+
"url": "git+https://github.com/TalAter/annyang.git"
|
|
13
|
+
},
|
|
14
|
+
"license": "MIT",
|
|
15
|
+
"author": "Tal Ater <tal@talater.com> (https://www.talater.com/)",
|
|
16
|
+
"type": "module",
|
|
17
|
+
"exports": {
|
|
18
|
+
".": {
|
|
19
|
+
"import": {
|
|
20
|
+
"types": "./dist/annyang.d.ts",
|
|
21
|
+
"default": "./dist/annyang.js"
|
|
22
|
+
},
|
|
23
|
+
"require": {
|
|
24
|
+
"types": "./dist/annyang.d.cts",
|
|
25
|
+
"default": "./dist/annyang.cjs"
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
},
|
|
29
|
+
"main": "./dist/annyang.cjs",
|
|
30
|
+
"module": "./dist/annyang.js",
|
|
31
|
+
"types": "./dist/annyang.d.ts",
|
|
32
|
+
"files": ["dist"],
|
|
33
|
+
"sideEffects": false,
|
|
34
|
+
"engines": {
|
|
35
|
+
"node": ">=18"
|
|
24
36
|
},
|
|
25
37
|
"scripts": {
|
|
26
|
-
"
|
|
27
|
-
"
|
|
38
|
+
"build": "tsup",
|
|
39
|
+
"dev": "tsup --watch",
|
|
40
|
+
"test": "vitest run",
|
|
41
|
+
"test:watch": "vitest",
|
|
42
|
+
"lint": "eslint src test",
|
|
43
|
+
"format": "prettier --write src test package.json",
|
|
44
|
+
"format:check": "prettier --check src test package.json",
|
|
45
|
+
"typecheck": "tsc --noEmit",
|
|
46
|
+
"docs": "typedoc && cat docs/api-intro.md docs/README.md docs/api-footer.md > docs/README.tmp && mv docs/README.tmp docs/README.md",
|
|
47
|
+
"test:manual": "pnpm build && cp dist/annyang.iife.min.js test-manual/ && npx esbuild test-manual/esm-app.js --bundle --alias:annyang=./dist/annyang.js --outfile=test-manual/dist/esm-app.js && npx esbuild test-manual/cjs-app.js --bundle --alias:annyang=./dist/annyang.cjs --outfile=test-manual/dist/cjs-app.js && npx http-server test-manual -p 8081 -c-1 -o",
|
|
48
|
+
"demo": "concurrently -n build,serve -c blue,green \"tsup --watch\" \"npx http-server . -p 8080 -c-1\"",
|
|
49
|
+
"prepublishOnly": "pnpm test && pnpm lint && pnpm typecheck && pnpm build && pnpm docs"
|
|
28
50
|
},
|
|
29
51
|
"devDependencies": {
|
|
30
|
-
"
|
|
31
|
-
"
|
|
32
|
-
"
|
|
33
|
-
"
|
|
34
|
-
"
|
|
35
|
-
"
|
|
36
|
-
"
|
|
37
|
-
"
|
|
38
|
-
"
|
|
39
|
-
"
|
|
40
|
-
"
|
|
41
|
-
"
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
"grunt-template-jasmine-requirejs": "^0.2.3",
|
|
46
|
-
"load-grunt-tasks": "^3.5.2"
|
|
47
|
-
}
|
|
48
|
-
}
|
|
52
|
+
"@types/dom-speech-recognition": "^0.0.7",
|
|
53
|
+
"concurrently": "^9.2.1",
|
|
54
|
+
"corti": "^2.1.0",
|
|
55
|
+
"eslint": "^10.0.2",
|
|
56
|
+
"eslint-config-prettier": "^10.1.8",
|
|
57
|
+
"prettier": "^3.8.1",
|
|
58
|
+
"tsup": "^8.5.1",
|
|
59
|
+
"typedoc": "^0.28.17",
|
|
60
|
+
"typedoc-plugin-markdown": "^4.10.0",
|
|
61
|
+
"typescript": "^5.9.3",
|
|
62
|
+
"typescript-eslint": "^8.56.1",
|
|
63
|
+
"vitest": "^4.0.18"
|
|
64
|
+
},
|
|
65
|
+
"packageManager": "pnpm@10.30.3"
|
|
66
|
+
}
|
package/.editorconfig
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
# EditorConfig helps developers define and maintain consistent
|
|
2
|
-
# coding styles between different editors and IDEs
|
|
3
|
-
# http://editorconfig.org
|
|
4
|
-
|
|
5
|
-
root = true
|
|
6
|
-
|
|
7
|
-
[*]
|
|
8
|
-
indent_style = space
|
|
9
|
-
indent_size = 2
|
|
10
|
-
end_of_line = lf
|
|
11
|
-
charset = utf-8
|
|
12
|
-
trim_trailing_whitespace = true
|
|
13
|
-
insert_final_newline = true
|
package/.eslintrc.json
DELETED
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"env": {
|
|
3
|
-
"browser": true,
|
|
4
|
-
"node": true
|
|
5
|
-
},
|
|
6
|
-
"extends": [
|
|
7
|
-
"eslint:recommended"
|
|
8
|
-
],
|
|
9
|
-
"parserOptions": {
|
|
10
|
-
"sourceType": "module"
|
|
11
|
-
},
|
|
12
|
-
"rules": {
|
|
13
|
-
"no-console": 0,
|
|
14
|
-
"indent": [
|
|
15
|
-
"error",
|
|
16
|
-
2
|
|
17
|
-
],
|
|
18
|
-
"linebreak-style": [
|
|
19
|
-
"error",
|
|
20
|
-
"unix"
|
|
21
|
-
],
|
|
22
|
-
"quotes": [
|
|
23
|
-
"error",
|
|
24
|
-
"single"
|
|
25
|
-
],
|
|
26
|
-
"semi": [
|
|
27
|
-
"error",
|
|
28
|
-
"always"
|
|
29
|
-
]
|
|
30
|
-
},
|
|
31
|
-
"globals": {
|
|
32
|
-
"define": false
|
|
33
|
-
}
|
|
34
|
-
}
|
package/.gitattributes
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
demo/* linguist-documentation
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
<!--- Provide a general summary of the issue in the Title above -->
|
|
2
|
-
|
|
3
|
-
## Expected Behavior
|
|
4
|
-
<!--- If you're describing a bug, tell us what should happen -->
|
|
5
|
-
<!--- If you're suggesting a change/improvement, tell us how it should work -->
|
|
6
|
-
|
|
7
|
-
## Current Behavior
|
|
8
|
-
<!--- If describing a bug, tell us what happens instead of the expected behavior -->
|
|
9
|
-
<!--- If suggesting a change/improvement, explain the difference from current behavior -->
|
|
10
|
-
|
|
11
|
-
## Possible Solution
|
|
12
|
-
<!--- Not obligatory, but suggest a fix/reason for the bug, -->
|
|
13
|
-
<!--- or ideas how to implement the addition or change -->
|
|
14
|
-
|
|
15
|
-
## Steps to Reproduce (for bugs)
|
|
16
|
-
<!--- Provide a link to a live example, or an unambiguous set of steps to -->
|
|
17
|
-
<!--- reproduce this bug. Include code to reproduce, if relevant -->
|
|
18
|
-
1.
|
|
19
|
-
2.
|
|
20
|
-
3.
|
|
21
|
-
4.
|
|
22
|
-
|
|
23
|
-
## Context
|
|
24
|
-
<!--- How has this issue affected you? What are you trying to accomplish? -->
|
|
25
|
-
<!--- Providing context helps us come up with a solution that is most useful in the real world -->
|
|
26
|
-
|
|
27
|
-
## Your Environment
|
|
28
|
-
<!--- Include as many relevant details about the environment you experienced the bug in -->
|
|
29
|
-
* Version used:
|
|
30
|
-
* Browser Name and version:
|
|
31
|
-
* Operating System and version (desktop or mobile):
|
|
32
|
-
* Link to your project:
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
<!--- Provide a general summary of your changes in the Title above -->
|
|
2
|
-
|
|
3
|
-
## Description
|
|
4
|
-
<!--- Describe your changes in detail -->
|
|
5
|
-
|
|
6
|
-
## Motivation and Context
|
|
7
|
-
<!--- Why is this change required? What problem does it solve? -->
|
|
8
|
-
<!--- If it fixes an open issue, please link to the issue here. -->
|
|
9
|
-
|
|
10
|
-
## How Has This Been Tested?
|
|
11
|
-
<!--- Please describe in detail how you tested your changes. -->
|
|
12
|
-
<!--- Include details of your testing environment, and the tests you ran to -->
|
|
13
|
-
<!--- see how your change affects other areas of the code, etc. -->
|
|
14
|
-
|
|
15
|
-
## Types of changes
|
|
16
|
-
<!--- What types of changes does your code introduce? Put an `x` in all the boxes that apply: -->
|
|
17
|
-
- [ ] Bug fix (non-breaking change which fixes an issue)
|
|
18
|
-
- [ ] New feature (non-breaking change which adds functionality)
|
|
19
|
-
- [ ] Breaking change (fix or feature that would cause existing functionality to change)
|
|
20
|
-
|
|
21
|
-
## Checklist:
|
|
22
|
-
<!--- Go over all the following points, and put an `x` in all the boxes that apply. -->
|
|
23
|
-
<!--- If you're unsure about any of these, don't hesitate to ask. We're here to help! -->
|
|
24
|
-
- [ ] My code follows the code style of this project.
|
|
25
|
-
- [ ] My change requires a change to the documentation.
|
|
26
|
-
- [ ] I have updated the documentation accordingly.
|
|
27
|
-
- [ ] I have read the **CONTRIBUTING** document.
|
|
28
|
-
- [ ] I have added tests to cover my changes.
|
|
29
|
-
- [ ] All new and existing tests passed.
|
package/.jshintrc
DELETED
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"node" : true,
|
|
3
|
-
"browser" : true,
|
|
4
|
-
"devel" : false,
|
|
5
|
-
"camelcase" : true,
|
|
6
|
-
"curly" : true,
|
|
7
|
-
"latedef" : true,
|
|
8
|
-
"unused" : true,
|
|
9
|
-
"trailing" : true,
|
|
10
|
-
"eqeqeq" : true,
|
|
11
|
-
"eqnull" : true,
|
|
12
|
-
"evil" : false,
|
|
13
|
-
"forin" : true,
|
|
14
|
-
"immed" : true,
|
|
15
|
-
"laxbreak" : false,
|
|
16
|
-
"newcap" : true,
|
|
17
|
-
"noarg" : true,
|
|
18
|
-
"noempty" : false,
|
|
19
|
-
"nonew" : true,
|
|
20
|
-
"onevar" : false,
|
|
21
|
-
"plusplus" : false,
|
|
22
|
-
"undef" : true,
|
|
23
|
-
"sub" : true,
|
|
24
|
-
"strict" : true,
|
|
25
|
-
"white" : false,
|
|
26
|
-
"indent" : 2,
|
|
27
|
-
"esversion" : 6,
|
|
28
|
-
"globals" : {
|
|
29
|
-
"define" : false
|
|
30
|
-
}
|
|
31
|
-
}
|
package/.travis.yml
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
sudo: false
|
|
2
|
-
language: node_js
|
|
3
|
-
node_js:
|
|
4
|
-
- '10'
|
|
5
|
-
- '9'
|
|
6
|
-
- '8'
|
|
7
|
-
- '7'
|
|
8
|
-
- '6'
|
|
9
|
-
- '5'
|
|
10
|
-
- 'node'
|
|
11
|
-
deploy:
|
|
12
|
-
provider: npm
|
|
13
|
-
email: tal@talater.com
|
|
14
|
-
api_key:
|
|
15
|
-
secure: B7djVh1jMSccBqDoFYO+yDcucgd5u7vR8dy6U1p48BKcA78bNlIm58MO2XF22Qx0uqKAv3piD385DgUoICoHU4Au9BXFBEdMpxbLsd4LVIOekPCnOlF2GHz9p8mhUzNbXP4qXLjoNz1tZlcd9LgSujN35PnNDp00AKdjs8vIceo=
|
|
16
|
-
on:
|
|
17
|
-
tags: true
|
|
18
|
-
branch: master
|
|
19
|
-
node: '5'
|
|
20
|
-
repo: TalAter/annyang
|
package/CONTRIBUTING.md
DELETED
|
@@ -1,75 +0,0 @@
|
|
|
1
|
-
# Contributing to annyang
|
|
2
|
-
|
|
3
|
-
Thank you for taking the time to get involved with annyang! :+1:
|
|
4
|
-
|
|
5
|
-
There are several ways you can help the project out:
|
|
6
|
-
|
|
7
|
-
* [Contributing code](#contributing-code)
|
|
8
|
-
* [Reporting Bugs](#reporting-bugs)
|
|
9
|
-
* [Feature Requests and Ideas](#feature-requests-and-ideas)
|
|
10
|
-
|
|
11
|
-
## How Can I Contribute?
|
|
12
|
-
|
|
13
|
-
### Contributing Code
|
|
14
|
-
|
|
15
|
-
A lot of annyang's functionality came from pull requests sent over GitHub. Here is how you can contribute too:
|
|
16
|
-
|
|
17
|
-
- [x] Fork the repository from the [annyang GitHub page](https://github.com/TalAter/annyang).
|
|
18
|
-
- [x] Clone a copy to your local machine with `$ git clone git@github.com:YOUR-GITHUB-USER-NAME/annyang.git`
|
|
19
|
-
- [x] Make sure you have *node.js* and *npm* installed on your machine. You can use this [guide](https://docs.npmjs.com/getting-started/installing-node) for help.
|
|
20
|
-
- [x] Install all of annyang's development dependencies with npm. `$ cd annyang; npm install`
|
|
21
|
-
- [x] If you do not have the grunt-cli installed globally, run `$ npm install -g grunt-cli`
|
|
22
|
-
- [x] Run grunt to make sure everything runs smoothly `$ grunt`
|
|
23
|
-
- [x] Add tests for your code. [See details below](#automated-testing).
|
|
24
|
-
- [x] Code, code, code. Changes should be done in `/src/annyang.js`. They will be transpiled to `/dist/annyang.js` and `/dist/annyang.min.js`.
|
|
25
|
-
- [x] Run `$ grunt` after making changes to verify that everything still works and the tests all pass.
|
|
26
|
-
|
|
27
|
-
:bulb: A great alternative to repeatedly running `$ grunt` is to run `$ grunt watch` once, and leave this process running. It will continuously run all the tests and build the files every time you make a change to one of annyang's files. It will even *beep* if you make an error, and help you debug it. :+1:
|
|
28
|
-
- [x] You can run a local server to test your work in the browser by running `$ grunt dev`. This will also automatically run `$ grunt watch` for you.
|
|
29
|
-
Point your browser to `https://localhost:8443/demo/` to see the demo page.
|
|
30
|
-
Since it's using self-signed certificate, you might need to click *"Proceed Anyway"*.
|
|
31
|
-
- [x] Before committing your changes, the last step must always be running `$ grunt`. This makes sure everything works, and all files are kept up to date with your changes.
|
|
32
|
-
- [x] Once you've made sure all your changes work correctly and have been committed, push your local changes back to github with `$ git push -u origin master`
|
|
33
|
-
- [x] Visit your fork on GitHub.com ([https://github.com/YOUR-USER-NAME/annyang](https://github.com/YOUR-USER-NAME/annyang)) and create a pull request for your changes.
|
|
34
|
-
- [x] Makes sure your pull request describes exactly what you changed and if it relates to an open issue references that issue (just include the issue number in the title like this: #49)
|
|
35
|
-
|
|
36
|
-
#### Important:
|
|
37
|
-
|
|
38
|
-
* Make sure to run `npm install` and `grunt` and make sure all tasks completed successfully before committing.
|
|
39
|
-
* Do not change the [API docs](https://github.com/TalAter/annyang/blob/master/docs/README.md) in `/docs/README.md` directly. This file is generated automatically, and your changes will be overwritten. Instead, update the relevant comments in `src/annyang.js`
|
|
40
|
-
* annyang is still not completely automatically tested :disappointed:. If you make a change, please make sure to test your change thoroughly to make sure no backward functionality was broken, and that your change works as intended.
|
|
41
|
-
* Do not update the version number yourself.
|
|
42
|
-
* Please stick to the project's existing coding style. Coding styles don't need to have a consensus, they just need to be consistent :smile:.
|
|
43
|
-
* Push your changes to a topic branch in your fork of the repository. Your branch should be based on the `master` branch.
|
|
44
|
-
* When submitting [pull request](https://help.github.com/articles/using-pull-requests/), please elaborate as much as possible about the change, your motivation for the change, etc.
|
|
45
|
-
|
|
46
|
-
#### Automated Testing
|
|
47
|
-
|
|
48
|
-
annyang is tested using [Jasmine](http://jasmine.github.io/2.0/introduction.html).
|
|
49
|
-
|
|
50
|
-
Please include tests for any changes you make:
|
|
51
|
-
* If you found a bug, please write a test that fails because of that bug, then fix the bug so that the test passes.
|
|
52
|
-
* If you are adding a new feature, write tests that thoroughly test every possible use of your code.
|
|
53
|
-
* If you are changing existing functionality, make sure to update existing tests so they pass. (This is a last resort. Whenever possible try to maintain backwards compatibility)
|
|
54
|
-
|
|
55
|
-
The tests reside in *BasicSpec.js*. The file contains a series of spec groups (e.g. `describe('a spec group', function() {});`) which each contain 1 or more specs (e.g. `it('should do stuff', function() {});`). Some of the spec groups also contain some code which runs before each spec (`beforeEach(function() {});`).
|
|
56
|
-
|
|
57
|
-
To simulate Speech Recognition in the testing environment, annyang uses a mock object called [Corti](https://github.com/TalAter/Corti) which mocks the browser's SpeechRecognition object. Corti also adds a number of utility functions to the SpeechRecognition object which simulate user actions (e.g. `say('Hello there')`), and allow checking the SpeechRecognition's status (e.g. `isListening() === true`).
|
|
58
|
-
|
|
59
|
-
### Reporting Bugs
|
|
60
|
-
|
|
61
|
-
Bugs are tracked as [GitHub issues](https://github.com/TalAter/annyang/issues). If you found a bug with annyang, the quickest way to get help would be to look through existing open and closed [GitHub issues](https://github.com/TalAter/annyang/issues?q=is%3Aissue). If the issue is already being discussed and hasn't been resolved yet, you can join the discussion and provide details about the problem you are having. If this is a new bug, please open a [new issue](https://github.com/TalAter/annyang/issues/new).
|
|
62
|
-
|
|
63
|
-
When you are creating a bug report, please include as many details as possible.
|
|
64
|
-
|
|
65
|
-
Explain the problem and include additional details to help maintainers reproduce the problem.
|
|
66
|
-
|
|
67
|
-
* Use a clear and descriptive title for the issue to identify the problem.
|
|
68
|
-
* Describe the exact steps which reproduce the problem. Share the relevant code to reproduce the issue if possible.
|
|
69
|
-
* Try to isolate the issue as much as possible, reducing unrelated code until you get to the minimal amount of code in which the bug still reproduces. This is the most important step to help the community solve the issue.
|
|
70
|
-
|
|
71
|
-
### Feature Requests and Ideas
|
|
72
|
-
|
|
73
|
-
We track discussions of new features, proposed changes and other ideas as [GitHub issues](https://github.com/TalAter/annyang/issues). If you would like to discuss one of those, please first look through existing open and closed [GitHub issues](https://github.com/TalAter/annyang/issues?q=is%3Aissue) and see if there is already a discussion on this topic which you can join. If there isn't, please open a [new issue](https://github.com/TalAter/annyang/issues/new).
|
|
74
|
-
|
|
75
|
-
When discussing new ideas or proposing changes, please take the time to be as descriptive as possible about the topic at hand. Please take the time to explain the issue you are facing, or the problem you propose to solve in as much detail as possible.
|