stimulus_reflex 3.5.0.pre8 → 3.5.0.pre9

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of stimulus_reflex might be problematic. Click here for more details.

Files changed (43) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +2 -1218
  3. data/Gemfile.lock +109 -152
  4. data/README.md +39 -5
  5. data/Rakefile +0 -8
  6. data/app/assets/javascripts/stimulus_reflex.js +969 -0
  7. data/app/assets/javascripts/stimulus_reflex.min.js +2 -0
  8. data/app/assets/javascripts/stimulus_reflex.min.js.map +1 -0
  9. data/app/assets/javascripts/stimulus_reflex.umd.js +904 -0
  10. data/app/assets/javascripts/stimulus_reflex.umd.min.js +905 -0
  11. data/app/assets/javascripts/stimulus_reflex.umd.min.js.map +1 -0
  12. data/app/channels/stimulus_reflex/channel.rb +20 -1
  13. data/lib/stimulus_reflex/engine.rb +29 -0
  14. data/lib/stimulus_reflex/importmap.rb +4 -0
  15. data/lib/stimulus_reflex/open_struct_fix.rb +29 -0
  16. data/lib/stimulus_reflex/reflex.rb +9 -2
  17. data/lib/stimulus_reflex/reflex_data.rb +4 -0
  18. data/lib/stimulus_reflex/reflex_factory.rb +2 -1
  19. data/lib/stimulus_reflex/utils/logger.rb +2 -0
  20. data/lib/stimulus_reflex/utils/sanity_checker.rb +0 -58
  21. data/lib/stimulus_reflex/version.rb +1 -1
  22. data/lib/stimulus_reflex.rb +2 -6
  23. data/package.json +67 -0
  24. data/rollup.config.js +85 -0
  25. data/stimulus_reflex.gemspec +63 -0
  26. data/test/broadcasters/broadcaster_test_case.rb +1 -1
  27. data/test/broadcasters/nothing_broadcaster_test.rb +2 -1
  28. data/test/broadcasters/page_broadcaster_test.rb +4 -2
  29. data/test/broadcasters/selector_broadcaster_test.rb +12 -6
  30. data/test/callbacks_test.rb +23 -23
  31. data/test/reflex_test.rb +2 -2
  32. data/test/tmp/app/reflexes/application_reflex.rb +3 -10
  33. data/test/tmp/app/reflexes/{demo_reflex.rb → user_reflex.rb} +10 -2
  34. data/web-test-runner.config.mjs +12 -0
  35. data/yarn-error.log +4964 -0
  36. data/yarn.lock +4520 -0
  37. metadata +107 -41
  38. data/lib/generators/USAGE +0 -14
  39. data/lib/generators/stimulus_reflex/templates/app/javascript/controllers/%file_name%_controller.js.tt +0 -101
  40. data/lib/generators/stimulus_reflex/templates/app/javascript/controllers/application_controller.js.tt +0 -60
  41. data/lib/generators/stimulus_reflex/templates/app/reflexes/%file_name%_reflex.rb.tt +0 -41
  42. data/lib/generators/stimulus_reflex/templates/app/reflexes/application_reflex.rb.tt +0 -19
  43. data/lib/tasks/stimulus_reflex/install.rake +0 -116
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stimulus_reflex.umd.min.js","sources":["../../../javascript/schema.js","../../../javascript/debug.js","../../../javascript/reflex_store.js","../../../javascript/log.js","../../../javascript/deprecate.js","../../../javascript/utils.js","../../../javascript/attributes.js","../../../javascript/isolation_mode.js","../../../javascript/lifecycle.js","../../../javascript/controllers.js","../../../javascript/reflexes.js","../../../javascript/reflex_data.js","../../../javascript/transports/action_cable.js","../../../javascript/callbacks.js","../../../javascript/stimulus_reflex.js","../../../javascript/index.js"],"sourcesContent":["const defaultSchema = {\n reflexAttribute: 'data-reflex',\n reflexPermanentAttribute: 'data-reflex-permanent',\n reflexRootAttribute: 'data-reflex-root',\n reflexSuppressLoggingAttribute: 'data-reflex-suppress-logging',\n reflexDatasetAttribute: 'data-reflex-dataset',\n reflexDatasetAllAttribute: 'data-reflex-dataset-all',\n reflexSerializeFormAttribute: 'data-reflex-serialize-form',\n reflexFormSelectorAttribute: 'data-reflex-form-selector',\n reflexIncludeInnerHtmlAttribute: 'data-reflex-include-inner-html',\n reflexIncludeTextContentAttribute: 'data-reflex-include-text-content'\n}\n\nlet schema = {}\n\nexport { schema, defaultSchema }\n\nexport default {\n set (application) {\n schema = { ...defaultSchema, ...application.schema }\n for (const attribute in schema) {\n Object.defineProperty(this, attribute.slice(0, -9), {\n get: () => {\n return schema[attribute]\n }\n })\n }\n }\n}\n","let debugging = false\n\nexport default {\n get enabled () {\n return debugging\n },\n get disabled () {\n return !debugging\n },\n get value () {\n return debugging\n },\n set (value) {\n debugging = !!value\n },\n set debug (value) {\n debugging = !!value\n }\n}\n","const reflexes = {}\n\nexport { reflexes }\n","import Debug from './debug'\n\nimport { reflexes } from './reflex_store'\n\nconst request = (\n reflexId,\n target,\n args,\n controller,\n element,\n controllerElement\n) => {\n const reflex = reflexes[reflexId]\n if (Debug.disabled || reflex.promise.data.suppressLogging) return\n reflex.timestamp = new Date()\n console.log(`\\u2191 stimulus \\u2191 ${target}`, {\n reflexId,\n args,\n controller,\n element,\n controllerElement\n })\n}\n\nconst success = (event, halted) => {\n const { detail } = event || {}\n const { selector, payload } = detail || {}\n const { reflexId, target, morph } = detail.stimulusReflex || {}\n const reflex = reflexes[reflexId]\n if (Debug.disabled || reflex.promise.data.suppressLogging) return\n const progress =\n reflex.totalOperations > 1\n ? ` ${reflex.completedOperations}/${reflex.totalOperations}`\n : ''\n const duration = reflex.timestamp\n ? `in ${new Date() - reflex.timestamp}ms`\n : 'CLONED'\n const operation = event.type\n .split(':')[1]\n .split('-')\n .slice(1)\n .join('_')\n console.log(\n `\\u2193 reflex \\u2193 ${target} \\u2192 ${selector ||\n '\\u221E'}${progress} ${duration}`,\n { reflexId, morph, operation, halted, payload }\n )\n}\n\nconst error = event => {\n const { detail } = event || {}\n const { reflexId, target, payload } = detail.stimulusReflex || {}\n const reflex = reflexes[reflexId]\n if (Debug.disabled || reflex.promise.data.suppressLogging) return\n const duration = reflex.timestamp\n ? `in ${new Date() - reflex.timestamp}ms`\n : 'CLONED'\n console.log(\n `\\u2193 reflex \\u2193 ${target} ${duration} %cERROR: ${event.detail.body}`,\n 'color: #f00;',\n { reflexId, payload }\n )\n}\n\nexport default { request, success, error }\n","let deprecationWarnings = true\n\nexport default {\n get enabled () {\n return deprecationWarnings\n },\n get disabled () {\n return !deprecationWarnings\n },\n get value () {\n return deprecationWarnings\n },\n set (value) {\n deprecationWarnings = !!value\n },\n set deprecate (value) {\n deprecationWarnings = !!value\n }\n}\n","// uuid4 function taken from stackoverflow\n// https://stackoverflow.com/a/2117523/554903\n\nconst uuidv4 = () => {\n const crypto = window.crypto || window.msCrypto\n return ([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, c =>\n (\n c ^\n (crypto.getRandomValues(new Uint8Array(1))[0] & (15 >> (c / 4)))\n ).toString(16)\n )\n}\n\nconst serializeForm = (form, options = {}) => {\n if (!form) return ''\n\n const w = options.w || window\n const { element } = options\n const formData = new w.FormData(form)\n const data = Array.from(formData, e => e.map(encodeURIComponent).join('='))\n const submitButton = form.querySelector('input[type=submit]')\n if (\n element &&\n element.name &&\n element.nodeName === 'INPUT' &&\n element.type === 'submit'\n ) {\n data.push(\n `${encodeURIComponent(element.name)}=${encodeURIComponent(element.value)}`\n )\n } else if (submitButton && submitButton.name) {\n data.push(\n `${encodeURIComponent(submitButton.name)}=${encodeURIComponent(\n submitButton.value\n )}`\n )\n }\n return Array.from(data).join('&')\n}\n\nconst camelize = (value, uppercaseFirstLetter = true) => {\n if (typeof value !== 'string') return ''\n value = value\n .replace(/[\\s_](.)/g, $1 => $1.toUpperCase())\n .replace(/[\\s_]/g, '')\n .replace(/^(.)/, $1 => $1.toLowerCase())\n\n if (uppercaseFirstLetter)\n value = value.substr(0, 1).toUpperCase() + value.substr(1)\n\n return value\n}\n\nconst debounce = (callback, delay = 250) => {\n let timeoutId\n return (...args) => {\n clearTimeout(timeoutId)\n timeoutId = setTimeout(() => {\n timeoutId = null\n callback(...args)\n }, delay)\n }\n}\n\nconst extractReflexName = reflexString => {\n const match = reflexString.match(/(?:.*->)?(.*?)(?:Reflex)?#/)\n\n return match ? match[1] : ''\n}\n\nconst emitEvent = (event, detail) => {\n document.dispatchEvent(\n new CustomEvent(event, {\n bubbles: true,\n cancelable: false,\n detail\n })\n )\n if (window.jQuery) window.jQuery(document).trigger(event, detail)\n}\n\n// construct a valid xPath for an element in the DOM\nconst elementToXPath = element => {\n if (element.id !== '') return \"//*[@id='\" + element.id + \"']\"\n if (element === document.body) return '/html/body'\n\n let ix = 0\n const siblings = element?.parentNode ? element.parentNode.childNodes : []\n\n for (var i = 0; i < siblings.length; i++) {\n const sibling = siblings[i]\n if (sibling === element) {\n const computedPath = elementToXPath(element.parentNode)\n const tagName = element.tagName.toLowerCase()\n const ixInc = ix + 1\n return `${computedPath}/${tagName}[${ixInc}]`\n }\n\n if (sibling.nodeType === 1 && sibling.tagName === element.tagName) {\n ix++\n }\n }\n}\n\nconst XPathToElement = xpath => {\n return document.evaluate(\n xpath,\n document,\n null,\n XPathResult.FIRST_ORDERED_NODE_TYPE,\n null\n ).singleNodeValue\n}\n\nconst XPathToArray = (xpath, reverse = false) => {\n const snapshotList = document.evaluate(\n xpath,\n document,\n null,\n XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,\n null\n )\n\n const snapshots = []\n\n for (let i = 0; i < snapshotList.snapshotLength; i++) {\n snapshots.push(snapshotList.snapshotItem(i))\n }\n\n return reverse ? snapshots.reverse() : snapshots\n}\n\nexport {\n uuidv4,\n serializeForm,\n camelize,\n debounce,\n extractReflexName,\n emitEvent,\n elementToXPath,\n XPathToElement,\n XPathToArray\n}\n","import Schema from './schema'\nimport Debug from './debug'\nimport Deprecate from './deprecate'\n\nimport { elementToXPath, XPathToArray } from './utils'\n\nconst multipleInstances = element => {\n if (['checkbox', 'radio'].includes(element.type)) {\n return (\n document.querySelectorAll(\n `input[type=\"${element.type}\"][name=\"${element.name}\"]`\n ).length > 1\n )\n }\n return false\n}\nconst collectCheckedOptions = element => {\n return Array.from(element.querySelectorAll('option:checked'))\n .concat(\n Array.from(\n document.querySelectorAll(\n `input[type=\"${element.type}\"][name=\"${element.name}\"]`\n )\n ).filter(elem => elem.checked)\n )\n .map(o => o.value)\n}\n\n// Returns a string value for the passed array.\n//\n// attributeValue(['', 'one', null, 'two', 'three ']) // 'one two three'\n//\nconst attributeValue = (values = []) => {\n const value = values\n .filter(v => v && String(v).length)\n .map(v => v.trim())\n .join(' ')\n .trim()\n return value.length ? value : null\n}\n\n// Returns an array for the passed string value by splitting on whitespace.\n//\n// attributeValues('one two three ') // ['one', 'two', 'three']\n//\nconst attributeValues = value => {\n if (!value) return []\n if (!value.length) return []\n return value.split(' ').filter(v => v.trim().length)\n}\n\n// Extracts attributes from a DOM element.\n//\nconst extractElementAttributes = element => {\n let attrs = Array.from(element.attributes).reduce((memo, attr) => {\n memo[attr.name] = attr.value\n return memo\n }, {})\n\n attrs.checked = !!element.checked\n attrs.selected = !!element.selected\n attrs.tag_name = element.tagName\n\n if (element.tagName.match(/select/i) || multipleInstances(element)) {\n const collectedOptions = collectCheckedOptions(element)\n attrs.values = collectedOptions\n attrs.value = collectedOptions.join(',')\n } else {\n attrs.value = element.value\n }\n return attrs\n}\n\n// Returns an array of elements for the provided tokens.\n// Tokens is an array of space separated string coming from the `data-reflex-dataset`\n// or `data-reflex-dataset-all` attribute.\n//\nconst getElementsFromTokens = (element, tokens) => {\n if (!tokens || tokens.length === 0) return []\n\n let elements = [element]\n\n const xPath = elementToXPath(element)\n\n tokens.forEach(token => {\n try {\n switch (token) {\n case 'combined':\n if (Deprecate.enabled)\n console.warn(\n \"In the next version of StimulusReflex, the 'combined' option to data-reflex-dataset will become 'ancestors'.\"\n )\n elements = [\n ...elements,\n ...XPathToArray(`${xPath}/ancestor::*`, true)\n ]\n break\n case 'ancestors':\n elements = [\n ...elements,\n ...XPathToArray(`${xPath}/ancestor::*`, true)\n ]\n break\n case 'parent':\n elements = [...elements, ...XPathToArray(`${xPath}/parent::*`)]\n break\n case 'siblings':\n elements = [\n ...elements,\n ...XPathToArray(\n `${xPath}/preceding-sibling::*|${xPath}/following-sibling::*`\n )\n ]\n break\n case 'children':\n elements = [...elements, ...XPathToArray(`${xPath}/child::*`)]\n break\n case 'descendants':\n elements = [...elements, ...XPathToArray(`${xPath}/descendant::*`)]\n break\n default:\n elements = [...elements, ...document.querySelectorAll(token)]\n }\n } catch (error) {\n if (Debug.enabled) console.error(error)\n }\n })\n\n return elements\n}\n\n// Extracts the dataset of an element and combines it with the data attributes from all specified tokens\n//\nconst extractElementDataset = element => {\n const dataset = element.attributes[Schema.reflexDataset]\n const allDataset = element.attributes[Schema.reflexDatasetAll]\n\n const tokens = (dataset && dataset.value.split(' ')) || []\n const allTokens = (allDataset && allDataset.value.split(' ')) || []\n\n const datasetElements = getElementsFromTokens(element, tokens)\n const datasetAllElements = getElementsFromTokens(element, allTokens)\n\n const datasetAttributes = datasetElements.reduce((acc, ele) => {\n return { ...extractDataAttributes(ele), ...acc }\n }, {})\n\n const reflexElementAttributes = extractDataAttributes(element)\n\n const elementDataset = {\n dataset: { ...reflexElementAttributes, ...datasetAttributes },\n datasetAll: {}\n }\n\n datasetAllElements.forEach(element => {\n const elementAttributes = extractDataAttributes(element)\n\n Object.keys(elementAttributes).forEach(key => {\n const value = elementAttributes[key]\n\n if (\n elementDataset.datasetAll[key] &&\n Array.isArray(elementDataset.datasetAll[key])\n ) {\n elementDataset.datasetAll[key].push(value)\n } else {\n elementDataset.datasetAll[key] = [value]\n }\n })\n })\n\n return elementDataset\n}\n\n// Extracts all data attributes from a DOM element.\n//\nconst extractDataAttributes = element => {\n let attrs = {}\n\n if (element && element.attributes) {\n Array.from(element.attributes).forEach(attr => {\n if (attr.name.startsWith('data-')) {\n attrs[attr.name] = attr.value\n }\n })\n }\n\n return attrs\n}\n\nexport {\n attributeValue,\n attributeValues,\n extractElementAttributes,\n extractElementDataset,\n extractDataAttributes\n}\n","let isolationMode = false\n\nexport default {\n get disabled () {\n return !isolationMode\n },\n set (value) {\n isolationMode = value\n }\n}\n","import Debug from './debug'\n\nimport { camelize } from './utils'\nimport { reflexes } from './reflex_store'\n\n// Invokes a lifecycle method on a StimulusReflex controller.\n//\n// - stage - the lifecycle stage\n// * before\n// * success\n// * error\n// * halted\n// * after\n// * finalize\n//\n// - reflexElement - the element that triggered the Reflex (not necessarily the StimulusReflex Controller Element)\n// - controllerElement - the element holding the StimulusReflex Controller\n// - reflexId - the UUIDv4 which uniquely identifies the Reflex\n// - payload - the optional \"return value\" from the Reflex method\n//\nconst invokeLifecycleMethod = (\n stage,\n reflexElement,\n controllerElement,\n reflexId,\n payload\n) => {\n if (!controllerElement || !controllerElement.reflexData[reflexId]) return\n\n const controller = controllerElement.reflexController[reflexId]\n const reflex = controllerElement.reflexData[reflexId].target\n const reflexMethodName = reflex.split('#')[1]\n\n const specificLifecycleMethodName = ['before', 'after', 'finalize'].includes(\n stage\n )\n ? `${stage}${camelize(reflexMethodName)}`\n : `${camelize(reflexMethodName, false)}${camelize(stage)}`\n const specificLifecycleMethod = controller[specificLifecycleMethodName]\n\n const genericLifecycleMethodName = ['before', 'after', 'finalize'].includes(\n stage\n )\n ? `${stage}Reflex`\n : `reflex${camelize(stage)}`\n const genericLifecycleMethod = controller[genericLifecycleMethodName]\n\n if (typeof specificLifecycleMethod === 'function') {\n specificLifecycleMethod.call(\n controller,\n reflexElement,\n reflex,\n controllerElement.reflexError[reflexId],\n reflexId,\n payload\n )\n }\n\n if (typeof genericLifecycleMethod === 'function') {\n genericLifecycleMethod.call(\n controller,\n reflexElement,\n reflex,\n controllerElement.reflexError[reflexId],\n reflexId,\n payload\n )\n }\n\n if (reflexes[reflexId] && stage === reflexes[reflexId].finalStage) {\n Reflect.deleteProperty(controllerElement.reflexController, reflexId)\n Reflect.deleteProperty(controllerElement.reflexData, reflexId)\n Reflect.deleteProperty(controllerElement.reflexError, reflexId)\n // Removing this on a trial basis\n // 1. Prevents race condition with CR broadcasts\n // 2. Planning to remove it for v4 as part of queueing refactor\n // 3. Removing reflexes shouldn't be the responsibility of the lifecycle subsystem\n // Reflect.deleteProperty(reflexes, reflexId)\n }\n}\n\ndocument.addEventListener(\n 'stimulus-reflex:before',\n event =>\n invokeLifecycleMethod(\n 'before',\n event.detail.element,\n event.detail.controller.element,\n event.detail.reflexId,\n event.detail.payload\n ),\n true\n)\n\ndocument.addEventListener(\n 'stimulus-reflex:success',\n event => {\n invokeLifecycleMethod(\n 'success',\n event.detail.element,\n event.detail.controller.element,\n event.detail.reflexId,\n event.detail.payload\n )\n dispatchLifecycleEvent(\n 'after',\n event.detail.element,\n event.detail.controller.element,\n event.detail.reflexId,\n event.detail.payload\n )\n },\n true\n)\n\ndocument.addEventListener(\n 'stimulus-reflex:nothing',\n event => {\n dispatchLifecycleEvent(\n 'success',\n event.detail.element,\n event.detail.controller.element,\n event.detail.reflexId,\n event.detail.payload\n )\n },\n true\n)\n\ndocument.addEventListener(\n 'stimulus-reflex:error',\n event => {\n invokeLifecycleMethod(\n 'error',\n event.detail.element,\n event.detail.controller.element,\n event.detail.reflexId,\n event.detail.payload\n )\n dispatchLifecycleEvent(\n 'after',\n event.detail.element,\n event.detail.controller.element,\n event.detail.reflexId,\n event.detail.payload\n )\n },\n true\n)\n\ndocument.addEventListener(\n 'stimulus-reflex:halted',\n event =>\n invokeLifecycleMethod(\n 'halted',\n event.detail.element,\n event.detail.controller.element,\n event.detail.reflexId,\n event.detail.payload\n ),\n true\n)\n\ndocument.addEventListener(\n 'stimulus-reflex:after',\n event =>\n invokeLifecycleMethod(\n 'after',\n event.detail.element,\n event.detail.controller.element,\n event.detail.reflexId,\n event.detail.payload\n ),\n true\n)\n\ndocument.addEventListener(\n 'stimulus-reflex:finalize',\n event =>\n invokeLifecycleMethod(\n 'finalize',\n event.detail.element,\n event.detail.controller.element,\n event.detail.reflexId,\n event.detail.payload\n ),\n true\n)\n\n// Dispatches a lifecycle event on document\n//\n// - stage - the lifecycle stage\n// * before\n// * success\n// * error\n// * halted\n// * after\n// * finalize\n//\n// - reflexElement - the element that triggered the Reflex (not necessarily the StimulusReflex Controller Element)\n//\n// - controllerElement - the element holding the StimulusReflex Controller\n//\n// - reflexId - the UUIDv4 which uniquely identifies the Reflex\n//\n// - payload - optional Reflex return value\n//\nconst dispatchLifecycleEvent = (\n stage,\n reflexElement,\n controllerElement,\n reflexId,\n payload\n) => {\n if (!controllerElement) {\n if (Debug.enabled && !reflexes[reflexId].warned) {\n console.warn(\n `StimulusReflex was not able execute callbacks or emit events for \"${stage}\" or later life-cycle stages for this Reflex. The StimulusReflex Controller Element is no longer present in the DOM. Could you move the StimulusReflex Controller to an element higher in your DOM?`\n )\n reflexes[reflexId].warned = true\n }\n return\n }\n\n if (\n !controllerElement.reflexController ||\n (controllerElement.reflexController &&\n !controllerElement.reflexController[reflexId])\n ) {\n if (Debug.enabled && !reflexes[reflexId].warned) {\n console.warn(\n `StimulusReflex detected that the StimulusReflex Controller responsible for this Reflex has been replaced with a new instance. Callbacks and events for \"${stage}\" or later life-cycle stages cannot be executed.`\n )\n reflexes[reflexId].warned = true\n }\n return\n }\n\n const { target } = controllerElement.reflexData[reflexId] || {}\n const controller = controllerElement.reflexController[reflexId] || {}\n const event = `stimulus-reflex:${stage}`\n const action = `${event}:${target.split('#')[1]}`\n const detail = {\n reflex: target,\n controller,\n reflexId,\n element: reflexElement,\n payload\n }\n const options = { bubbles: true, cancelable: false, detail }\n\n controllerElement.dispatchEvent(new CustomEvent(event, options))\n controllerElement.dispatchEvent(new CustomEvent(action, options))\n\n if (window.jQuery) {\n window.jQuery(controllerElement).trigger(event, detail)\n window.jQuery(controllerElement).trigger(action, detail)\n }\n}\n\nexport { dispatchLifecycleEvent }\n","import Schema from './schema'\n\nimport { attributeValues } from './attributes'\nimport { extractReflexName } from './utils'\n\n// Returns StimulusReflex controllers local to the passed element based on the data-controller attribute.\n//\nconst localReflexControllers = (app, element) => {\n return attributeValues(element.getAttribute(Schema.controller)).reduce(\n (memo, name) => {\n const controller = app.getControllerForElementAndIdentifier(element, name)\n if (controller && controller.StimulusReflex) memo.push(controller)\n return memo\n },\n []\n )\n}\n\n// Returns all StimulusReflex controllers for the passed element.\n// Traverses DOM ancestors starting with element.\n//\nconst allReflexControllers = (app, element) => {\n let controllers = []\n while (element) {\n controllers = controllers.concat(localReflexControllers(app, element))\n element = element.parentElement\n }\n return controllers\n}\n\n// Given a reflex string such as 'click->TestReflex#create' and a list of\n// controllers. It will find the matching controller based on the controller's\n// identifier. e.g. Given these controller identifiers ['foo', 'bar', 'test'],\n// it would select the 'test' controller.\nconst findControllerByReflexName = (reflexName, controllers) => {\n const controller = controllers.find(controller => {\n if (!controller.identifier) return\n\n return (\n extractReflexName(reflexName)\n .replace(/([a-z0–9])([A-Z])/g, '$1-$2')\n .replace(/(::)/g, '--')\n .toLowerCase() === controller.identifier\n )\n })\n\n return controller || controllers[0]\n}\n\nexport { allReflexControllers, findControllerByReflexName }\n","import CableReady from 'cable_ready'\n\nimport Debug from './debug'\nimport Schema from './schema'\nimport IsolationMode from './isolation_mode'\n\nimport { reflexes } from './reflex_store'\nimport { dispatchLifecycleEvent } from './lifecycle'\nimport { XPathToElement, debounce, emitEvent } from './utils'\nimport { allReflexControllers, findControllerByReflexName } from './controllers'\nimport { attributeValue, attributeValues } from './attributes'\n\nconst received = data => {\n if (!data.cableReady) return\n\n if (data.version.replace('.pre', '-pre') !== CableReady.version) {\n if (Debug.enabled)\n console.error(\n `Reflex failed due to cable_ready gem/NPM package version mismatch. Package versions must match exactly.\\nNote that if you are using pre-release builds, gems use the \"x.y.z.preN\" version format, while NPM packages use \"x.y.z-preN\".\\n\\ncable_ready gem: ${data.version}\\ncable_ready NPM: ${CableReady.version}`\n )\n return\n }\n\n let reflexOperations = []\n\n for (let i = data.operations.length - 1; i >= 0; i--) {\n if (data.operations[i].stimulusReflex) {\n reflexOperations.push(data.operations[i])\n data.operations.splice(i, 1)\n }\n }\n\n if (\n reflexOperations.some(\n operation => operation.stimulusReflex.url !== location.href\n )\n ) {\n return\n }\n\n let reflexData\n\n if (reflexOperations.length) {\n reflexData = reflexOperations[0].stimulusReflex\n reflexData.payload = reflexOperations[0].payload\n }\n\n if (reflexData) {\n const { reflexId, payload } = reflexData\n\n if (!reflexes[reflexId] && IsolationMode.disabled) {\n const controllerElement = XPathToElement(reflexData.xpathController)\n const reflexElement = XPathToElement(reflexData.xpathElement)\n\n controllerElement.reflexController =\n controllerElement.reflexController || {}\n controllerElement.reflexData = controllerElement.reflexData || {}\n controllerElement.reflexError = controllerElement.reflexError || {}\n\n controllerElement.reflexController[\n reflexId\n ] = reflexes.app.getControllerForElementAndIdentifier(\n controllerElement,\n reflexData.reflexController\n )\n\n controllerElement.reflexData[reflexId] = reflexData\n\n dispatchLifecycleEvent(\n 'before',\n reflexElement,\n controllerElement,\n reflexId,\n payload\n )\n\n registerReflex(reflexData)\n }\n\n if (reflexes[reflexId]) {\n reflexes[reflexId].totalOperations = reflexOperations.length\n reflexes[reflexId].pendingOperations = reflexOperations.length\n reflexes[reflexId].completedOperations = 0\n reflexes[reflexId].piggybackOperations = data.operations\n CableReady.perform(reflexOperations)\n }\n } else {\n if (data.operations.length && reflexes[data.operations[0].reflexId]) {\n CableReady.perform(data.operations)\n }\n }\n}\n\nconst registerReflex = data => {\n const { reflexId } = data\n reflexes[reflexId] = { finalStage: 'finalize' }\n\n const promise = new Promise((resolve, reject) => {\n reflexes[reflexId].promise = {\n resolve,\n reject,\n data\n }\n })\n\n promise.reflexId = reflexId\n\n if (Debug.enabled) promise.catch(() => {})\n\n return promise\n}\n\n// compute the DOM element(s) which will be the morph root\n// use the data-reflex-root attribute on the reflex or the controller\n// optional value is a CSS selector(s); comma-separated list\n// order of preference is data-reflex, data-controller, document body (default)\nconst getReflexRoots = element => {\n let list = []\n while (list.length === 0 && element) {\n let reflexRoot = element.getAttribute(Schema.reflexRoot)\n if (reflexRoot) {\n if (reflexRoot.length === 0 && element.id) reflexRoot = `#${element.id}`\n const selectors = reflexRoot.split(',').filter(s => s.trim().length)\n if (Debug.enabled && selectors.length === 0) {\n console.error(\n `No value found for ${Schema.reflexRoot}. Add an #id to the element or provide a value for ${Schema.reflexRoot}.`,\n element\n )\n }\n list = list.concat(selectors.filter(s => document.querySelector(s)))\n }\n element = element.parentElement\n ? element.parentElement.closest(`[${Schema.reflexRoot}]`)\n : null\n }\n return list\n}\n\n// Sets up declarative reflex behavior.\n// Any elements that define data-reflex will automatically be wired up with the default StimulusReflexController.\n//\nconst setupDeclarativeReflexes = debounce(() => {\n document.querySelectorAll(`[${Schema.reflex}]`).forEach(element => {\n const controllers = attributeValues(element.getAttribute(Schema.controller))\n const reflexAttributeNames = attributeValues(\n element.getAttribute(Schema.reflex)\n )\n const actions = attributeValues(element.getAttribute(Schema.action))\n reflexAttributeNames.forEach(reflexName => {\n const controller = findControllerByReflexName(\n reflexName,\n allReflexControllers(reflexes.app, element)\n )\n let action\n if (controller) {\n action = `${reflexName.split('->')[0]}->${\n controller.identifier\n }#__perform`\n if (!actions.includes(action)) actions.push(action)\n } else {\n action = `${reflexName.split('->')[0]}->stimulus-reflex#__perform`\n if (!controllers.includes('stimulus-reflex')) {\n controllers.push('stimulus-reflex')\n }\n if (!actions.includes(action)) actions.push(action)\n }\n })\n const controllerValue = attributeValue(controllers)\n const actionValue = attributeValue(actions)\n if (\n controllerValue &&\n element.getAttribute(Schema.controller) != controllerValue\n ) {\n element.setAttribute(Schema.controller, controllerValue)\n }\n if (actionValue && element.getAttribute(Schema.action) != actionValue)\n element.setAttribute(Schema.action, actionValue)\n })\n emitEvent('stimulus-reflex:ready')\n}, 20)\n\nexport { received, registerReflex, getReflexRoots, setupDeclarativeReflexes }\n","import Schema from './schema'\n\nimport { extractElementAttributes, extractElementDataset } from './attributes'\nimport { getReflexRoots } from './reflexes'\nimport { uuidv4 } from './utils'\nimport { elementToXPath } from './utils'\n\nimport { version } from '../package.json'\n\nexport default class ReflexData {\n constructor (\n options,\n reflexElement,\n controllerElement,\n reflexController,\n permanentAttributeName,\n target,\n args,\n url,\n tabId\n ) {\n this.options = options\n this.reflexElement = reflexElement\n this.controllerElement = controllerElement\n this.reflexController = reflexController\n this.permanentAttributeName = permanentAttributeName\n this.target = target\n this.args = args\n this.url = url\n this.tabId = tabId\n }\n\n get attrs () {\n this._attrs =\n this._attrs ||\n this.options['attrs'] ||\n extractElementAttributes(this.reflexElement)\n\n return this._attrs\n }\n\n get reflexId () {\n this._reflexId = this._reflexId || this.options['reflexId'] || uuidv4()\n return this._reflexId\n }\n\n get selectors () {\n this._selectors =\n this._selectors ||\n this.options['selectors'] ||\n getReflexRoots(this.reflexElement)\n\n return typeof this._selectors === 'string'\n ? [this._selectors]\n : this._selectors\n }\n\n get resolveLate () {\n return this.options['resolveLate'] || false\n }\n\n get dataset () {\n this._dataset = this._dataset || extractElementDataset(this.reflexElement)\n return this._dataset\n }\n\n get innerHTML () {\n return this.includeInnerHtml ? this.reflexElement.innerHTML : ''\n }\n\n get textContent () {\n return this.includeTextContent ? this.reflexElement.textContent : ''\n }\n\n get xpathController () {\n return elementToXPath(this.controllerElement)\n }\n\n get xpathElement () {\n return elementToXPath(this.reflexElement)\n }\n\n get formSelector () {\n const attr = this.reflexElement.attributes[Schema.reflexFormSelector]\n ? this.reflexElement.attributes[Schema.reflexFormSelector].value\n : undefined\n return this.options['formSelector'] || attr\n }\n\n get includeInnerHtml () {\n const attr =\n this.reflexElement.attributes[Schema.reflexIncludeInnerHtml] || false\n return this.options['includeInnerHTML'] || attr\n ? attr.value !== 'false'\n : false\n }\n\n get includeTextContent () {\n const attr =\n this.reflexElement.attributes[Schema.reflexIncludeTextContent] || false\n return this.options['includeTextContent'] || attr\n ? attr.value !== 'false'\n : false\n }\n\n get suppressLogging () {\n return (\n this.options['suppressLogging'] ||\n this.reflexElement.attributes[Schema.reflexSuppressLogging] ||\n false\n )\n }\n\n valueOf () {\n return {\n attrs: this.attrs,\n dataset: this.dataset,\n selectors: this.selectors,\n reflexId: this.reflexId,\n resolveLate: this.resolveLate,\n suppressLogging: this.suppressLogging,\n xpathController: this.xpathController,\n xpathElement: this.xpathElement,\n inner_html: this.innerHTML,\n text_content: this.textContent,\n formSelector: this.formSelector,\n reflexController: this.reflexController,\n permanentAttributeName: this.permanentAttributeName,\n target: this.target,\n args: this.args,\n url: this.url,\n tabId: this.tabId,\n version\n }\n }\n}\n","import { createConsumer } from '@rails/actioncable'\nimport { received } from '../reflexes'\nimport { emitEvent } from '../utils'\n\nlet consumer\nlet params\nlet subscriptionActive\n\nconst createSubscription = controller => {\n consumer = consumer || controller.application.consumer || createConsumer()\n const { channel } = controller.StimulusReflex\n const subscription = { channel, ...params }\n const identifier = JSON.stringify(subscription)\n\n controller.StimulusReflex.subscription =\n consumer.subscriptions.findAll(identifier)[0] ||\n consumer.subscriptions.create(subscription, {\n received,\n connected,\n rejected,\n disconnected\n })\n}\n\nconst connected = () => {\n subscriptionActive = true\n document.body.classList.replace(\n 'stimulus-reflex-disconnected',\n 'stimulus-reflex-connected'\n )\n emitEvent('stimulus-reflex:connected')\n emitEvent('stimulus-reflex:action-cable:connected')\n}\n\nconst rejected = () => {\n subscriptionActive = false\n document.body.classList.replace(\n 'stimulus-reflex-connected',\n 'stimulus-reflex-disconnected'\n )\n emitEvent('stimulus-reflex:rejected')\n emitEvent('stimulus-reflex:action-cable:rejected')\n if (Debug.enabled) console.warn('Channel subscription was rejected.')\n}\n\nconst disconnected = willAttemptReconnect => {\n subscriptionActive = false\n document.body.classList.replace(\n 'stimulus-reflex-connected',\n 'stimulus-reflex-disconnected'\n )\n emitEvent('stimulus-reflex:disconnected', willAttemptReconnect)\n emitEvent('stimulus-reflex:action-cable:disconnected', willAttemptReconnect)\n}\n\nexport default {\n consumer,\n params,\n get subscriptionActive () {\n return subscriptionActive\n },\n createSubscription,\n connected,\n rejected,\n disconnected,\n set (consumerValue, paramsValue) {\n consumer = consumerValue\n params = paramsValue\n }\n}\n","import CableReady from 'cable_ready'\n\nimport Log from './log'\n\nimport { reflexes } from './reflex_store'\nimport { dispatchLifecycleEvent } from './lifecycle'\nimport { XPathToElement } from './utils'\n\nconst beforeDOMUpdate = event => {\n const { stimulusReflex, payload } = event.detail || {}\n if (!stimulusReflex) return\n const { reflexId, xpathElement, xpathController } = stimulusReflex\n const controllerElement = XPathToElement(xpathController)\n const reflexElement = XPathToElement(xpathElement)\n const reflex = reflexes[reflexId]\n const { promise } = reflex\n\n reflex.pendingOperations--\n\n if (reflex.pendingOperations > 0) return\n\n if (!stimulusReflex.resolveLate)\n setTimeout(() =>\n promise.resolve({\n element: reflexElement,\n event,\n data: promise.data,\n payload,\n reflexId,\n toString: () => ''\n })\n )\n\n setTimeout(() =>\n dispatchLifecycleEvent(\n 'success',\n reflexElement,\n controllerElement,\n reflexId,\n payload\n )\n )\n}\n\nconst afterDOMUpdate = event => {\n const { stimulusReflex, payload } = event.detail || {}\n if (!stimulusReflex) return\n const { reflexId, xpathElement, xpathController } = stimulusReflex\n const controllerElement = XPathToElement(xpathController)\n const reflexElement = XPathToElement(xpathElement)\n const reflex = reflexes[reflexId]\n const { promise } = reflex\n\n reflex.completedOperations++\n\n Log.success(event, false)\n\n if (reflex.completedOperations < reflex.totalOperations) return\n\n if (stimulusReflex.resolveLate)\n setTimeout(() =>\n promise.resolve({\n element: reflexElement,\n event,\n data: promise.data,\n payload,\n reflexId,\n toString: () => ''\n })\n )\n\n setTimeout(() =>\n dispatchLifecycleEvent(\n 'finalize',\n reflexElement,\n controllerElement,\n reflexId,\n payload\n )\n )\n\n if (reflex.piggybackOperations.length)\n CableReady.perform(reflex.piggybackOperations)\n}\n\nconst routeReflexEvent = event => {\n const { stimulusReflex, payload, name, body } = event.detail || {}\n const eventType = name.split('-')[2]\n if (!stimulusReflex || !['nothing', 'halted', 'error'].includes(eventType))\n return\n\n const { reflexId, xpathElement, xpathController } = stimulusReflex\n const reflexElement = XPathToElement(xpathElement)\n const controllerElement = XPathToElement(xpathController)\n const reflex = reflexes[reflexId]\n const { promise } = reflex\n\n if (controllerElement) {\n controllerElement.reflexError = controllerElement.reflexError || {}\n if (eventType === 'error') controllerElement.reflexError[reflexId] = body\n }\n\n switch (eventType) {\n case 'nothing':\n nothing(event, payload, promise, reflex, reflexElement)\n break\n case 'error':\n error(event, payload, promise, reflex, reflexElement)\n break\n case 'halted':\n halted(event, payload, promise, reflex, reflexElement)\n break\n }\n\n setTimeout(() =>\n dispatchLifecycleEvent(\n eventType,\n reflexElement,\n controllerElement,\n reflexId,\n payload\n )\n )\n\n if (reflex.piggybackOperations.length)\n CableReady.perform(reflex.piggybackOperations)\n}\n\nconst nothing = (event, payload, promise, reflex, reflexElement) => {\n reflex.finalStage = 'after'\n\n Log.success(event, false)\n\n setTimeout(() =>\n promise.resolve({\n data: promise.data,\n element: reflexElement,\n event,\n payload,\n reflexId: promise.data.reflexId,\n toString: () => ''\n })\n )\n}\n\nconst halted = (event, payload, promise, reflex, reflexElement) => {\n reflex.finalStage = 'halted'\n\n Log.success(event, true)\n\n setTimeout(() =>\n promise.resolve({\n data: promise.data,\n element: reflexElement,\n event,\n payload,\n reflexId: promise.data.reflexId,\n toString: () => ''\n })\n )\n}\n\nconst error = (event, payload, promise, reflex, reflexElement) => {\n reflex.finalStage = 'after'\n\n Log.error(event)\n\n setTimeout(() =>\n promise.reject({\n data: promise.data,\n element: reflexElement,\n event,\n payload,\n reflexId: promise.data.reflexId,\n error: event.detail.body,\n toString: () => event.detail.body\n })\n )\n}\n\nexport { beforeDOMUpdate, afterDOMUpdate, routeReflexEvent }\n","import { Controller } from '@hotwired/stimulus'\n\nimport Schema from './schema'\nimport Log from './log'\nimport Debug from './debug'\nimport Deprecate from './deprecate'\nimport ReflexData from './reflex_data'\nimport IsolationMode from './isolation_mode'\nimport ActionCableTransport from './transports/action_cable'\n\nimport { dispatchLifecycleEvent } from './lifecycle'\nimport { uuidv4, serializeForm } from './utils'\nimport { beforeDOMUpdate, afterDOMUpdate, routeReflexEvent } from './callbacks'\nimport { registerReflex, setupDeclarativeReflexes } from './reflexes'\nimport { reflexes } from './reflex_store'\nimport { attributeValues } from './attributes'\n\n// Default StimulusReflexController that is implicitly wired up as data-controller for any DOM elements\n// that have configured data-reflex. Note that this default can be overridden when initializing the application.\n// i.e. StimulusReflex.initialize(myStimulusApplication, MyCustomDefaultController);\n//\nclass StimulusReflexController extends Controller {\n constructor (...args) {\n super(...args)\n register(this)\n }\n}\n\n// Initializes StimulusReflex by registering the default Stimulus controller with the passed Stimulus application.\n//\n// - application - the Stimulus application\n// - options\n// * controller - [optional] the default StimulusReflexController\n// * consumer - [optional] the ActionCable consumer\n// * debug - [false] log all Reflexes to the console\n// * params - [{}] key/value parameters to send during channel subscription\n// * isolate - [false] restrict Reflex playback to the tab which initiated it\n// * deprecate - [true] show warnings regarding upcoming changes to the library\n//\nconst initialize = (\n application,\n { controller, consumer, debug, params, isolate, deprecate } = {}\n) => {\n ActionCableTransport.set(consumer, params)\n document.addEventListener(\n 'DOMContentLoaded',\n () => {\n document.body.classList.remove('stimulus-reflex-connected')\n document.body.classList.add('stimulus-reflex-disconnected')\n if (Deprecate.enabled && consumer)\n console.warn(\n \"Deprecation warning: the next version of StimulusReflex will obtain a reference to consumer via the Stimulus application object.\\nPlease add 'application.consumer = consumer' to your index.js after your Stimulus application has been established, and remove the consumer key from your StimulusReflex initialize() options object.\"\n )\n if (Deprecate.enabled && IsolationMode.disabled)\n console.warn(\n 'Deprecation warning: the next version of StimulusReflex will standardize isolation mode, and the isolate option will be removed.\\nPlease update your applications to assume that every tab will be isolated.'\n )\n },\n { once: true }\n )\n IsolationMode.set(!!isolate)\n reflexes.app = application\n Schema.set(application)\n reflexes.app.register(\n 'stimulus-reflex',\n controller || StimulusReflexController\n )\n Debug.set(!!debug)\n if (typeof deprecate !== 'undefined') Deprecate.set(deprecate)\n const observer = new MutationObserver(setupDeclarativeReflexes)\n observer.observe(document.documentElement, {\n attributeFilter: [Schema.reflex, Schema.action],\n childList: true,\n subtree: true\n })\n}\n\n// Registers a Stimulus controller and extends it with StimulusReflex behavior\n//\n// controller - the Stimulus controller\n// options - [optional] configuration\n//\nconst register = (controller, options = {}) => {\n const channel = 'StimulusReflex::Channel'\n controller.StimulusReflex = { ...options, channel }\n ActionCableTransport.createSubscription(controller)\n Object.assign(controller, {\n // Indicates if the ActionCable web socket connection is open.\n // The connection must be open before calling stimulate.\n //\n isActionCableConnectionOpen () {\n return this.StimulusReflex.subscription.consumer.connection.isOpen()\n },\n\n // Invokes a server side reflex method.\n //\n // - target - the reflex target (full name of the server side reflex) i.e. 'ReflexClassName#method'\n // - reflexElement - [optional] the element that triggered the reflex, defaults to this.element\n // - options - [optional] an object that contains at least one of attrs, reflexId, selectors, resolveLate, serializeForm\n // - *args - remaining arguments are forwarded to the server side reflex method\n //\n stimulate () {\n const url = location.href\n const args = Array.from(arguments)\n const target = args.shift() || 'StimulusReflex::Reflex#default_reflex'\n const controllerElement = this.element\n const reflexElement =\n args[0] && args[0].nodeType === Node.ELEMENT_NODE\n ? args.shift()\n : controllerElement\n if (\n reflexElement.type === 'number' &&\n reflexElement.validity &&\n reflexElement.validity.badInput\n ) {\n if (Debug.enabled) console.warn('Reflex aborted: invalid numeric input')\n return\n }\n const options = {}\n if (\n args[0] &&\n typeof args[0] === 'object' &&\n Object.keys(args[0]).filter(key =>\n [\n 'attrs',\n 'selectors',\n 'reflexId',\n 'resolveLate',\n 'serializeForm',\n 'suppressLogging',\n 'includeInnerHTML',\n 'includeTextContent'\n ].includes(key)\n ).length\n ) {\n const opts = args.shift()\n Object.keys(opts).forEach(o => (options[o] = opts[o]))\n }\n\n const reflexData = new ReflexData(\n options,\n reflexElement,\n controllerElement,\n this.identifier,\n Schema.reflexPermanent,\n target,\n args,\n url,\n tabId\n )\n\n const reflexId = reflexData.reflexId\n\n if (!this.isActionCableConnectionOpen())\n throw 'The ActionCable connection is not open! `this.isActionCableConnectionOpen()` must return true before calling `this.stimulate()`'\n\n if (!ActionCableTransport.subscriptionActive)\n throw 'The ActionCable channel subscription for StimulusReflex was rejected.'\n\n // lifecycle setup\n controllerElement.reflexController =\n controllerElement.reflexController || {}\n controllerElement.reflexData = controllerElement.reflexData || {}\n controllerElement.reflexError = controllerElement.reflexError || {}\n\n controllerElement.reflexController[reflexId] = this\n controllerElement.reflexData[reflexId] = reflexData.valueOf()\n\n dispatchLifecycleEvent(\n 'before',\n reflexElement,\n controllerElement,\n reflexId\n )\n\n setTimeout(() => {\n const { params } = controllerElement.reflexData[reflexId] || {}\n const check = reflexElement.attributes[Schema.reflexSerializeForm]\n if (check) {\n // not needed after v4 because this is only here for the deprecation warning\n options['serializeForm'] = check.value !== 'false'\n }\n\n const form =\n reflexElement.closest(reflexData.formSelector) ||\n document.querySelector(reflexData.formSelector) ||\n reflexElement.closest('form')\n\n if (Deprecate.enabled && options['serializeForm'] === undefined && form)\n console.warn(\n `Deprecation warning: the next version of StimulusReflex will not serialize forms by default.\\nPlease set ${Schema.reflexSerializeForm}=\\\"true\\\" on your Reflex Controller Element or pass { serializeForm: true } as an option to stimulate.`\n )\n const formData =\n options['serializeForm'] === false\n ? ''\n : serializeForm(form, {\n element: reflexElement\n })\n\n controllerElement.reflexData[reflexId] = {\n ...reflexData.valueOf(),\n params,\n formData\n }\n\n this.StimulusReflex.subscription.send(\n controllerElement.reflexData[reflexId]\n )\n })\n\n const promise = registerReflex(reflexData.valueOf())\n\n Log.request(\n reflexId,\n target,\n args,\n this.context.scope.identifier,\n reflexElement,\n controllerElement\n )\n\n return promise\n },\n\n // Wraps the call to stimulate for any data-reflex elements.\n // This is internal and should not be invoked directly.\n __perform (event) {\n let element = event.target\n let reflex\n\n while (element && !reflex) {\n reflex = element.getAttribute(Schema.reflex)\n if (!reflex || !reflex.trim().length) element = element.parentElement\n }\n\n const match = attributeValues(reflex).find(\n reflex => reflex.split('->')[0] === event.type\n )\n\n if (match) {\n event.preventDefault()\n event.stopPropagation()\n this.stimulate(match.split('->')[1], element)\n }\n }\n })\n}\n\n// Uniquely identify this browser tab in each Reflex\nconst tabId = uuidv4()\n\nconst useReflex = (controller, options = {}) => {\n register(controller, options)\n}\n\ndocument.addEventListener('cable-ready:after-dispatch-event', routeReflexEvent)\ndocument.addEventListener('cable-ready:before-inner-html', beforeDOMUpdate)\ndocument.addEventListener('cable-ready:before-morph', beforeDOMUpdate)\ndocument.addEventListener('cable-ready:after-inner-html', afterDOMUpdate)\ndocument.addEventListener('cable-ready:after-morph', afterDOMUpdate)\nwindow.addEventListener('load', setupDeclarativeReflexes)\n\nexport {\n initialize,\n register,\n useReflex\n}\n","export * from './stimulus_reflex'\n\nimport * as StimulusReflex from './stimulus_reflex'\n\nimport Debug from './debug'\nimport Deprecate from './deprecate'\n\nconst global = {\n ...StimulusReflex,\n get debug () {\n return Debug.value\n },\n set debug (value) {\n Debug.set(!!value)\n },\n get deprecate () {\n return Deprecate.value\n },\n set deprecate (value) {\n Deprecate.set(!!value)\n }\n}\n\nwindow.StimulusReflex = global\n\nexport default global\n"],"names":["defaultSchema","reflexAttribute","reflexPermanentAttribute","reflexRootAttribute","reflexSuppressLoggingAttribute","reflexDatasetAttribute","reflexDatasetAllAttribute","reflexSerializeFormAttribute","reflexFormSelectorAttribute","reflexIncludeInnerHtmlAttribute","reflexIncludeTextContentAttribute","schema","Schema","set","application","attribute","Object","defineProperty","this","slice","get","debugging","Debug$1","enabled","disabled","value","debug","reflexes","request","reflexId","target","args","controller","element","controllerElement","reflex","Debug","promise","data","suppressLogging","timestamp","Date","console","log","success","event","halted","detail","selector","payload","morph","stimulusReflex","progress","totalOperations","completedOperations","duration","operation","type","split","join","error","body","Log","deprecationWarnings","Deprecate","deprecate","uuidv4","crypto","window","msCrypto","replace","c","getRandomValues","Uint8Array","toString","serializeForm","form","options","w","formData","FormData","Array","from","e","map","encodeURIComponent","submitButton","querySelector","name","nodeName","push","camelize","uppercaseFirstLetter","$1","toUpperCase","toLowerCase","substr","debounce","callback","delay","timeoutId","clearTimeout","setTimeout","extractReflexName","reflexString","match","emitEvent","document","dispatchEvent","CustomEvent","bubbles","cancelable","jQuery","trigger","elementToXPath","id","ix","siblings","parentNode","childNodes","i","length","sibling","computedPath","tagName","ixInc","nodeType","XPathToElement","xpath","evaluate","XPathResult","FIRST_ORDERED_NODE_TYPE","singleNodeValue","XPathToArray","reverse","snapshotList","ORDERED_NODE_SNAPSHOT_TYPE","snapshots","snapshotLength","snapshotItem","multipleInstances","includes","querySelectorAll","collectCheckedOptions","concat","filter","elem","checked","o","attributeValue","values","v","String","trim","attributeValues","extractElementAttributes","attrs","attributes","reduce","memo","attr","selected","tag_name","collectedOptions","getElementsFromTokens","tokens","elements","xPath","forEach","token","warn","extractElementDataset","dataset","reflexDataset","allDataset","reflexDatasetAll","allTokens","datasetElements","datasetAllElements","datasetAttributes","acc","ele","extractDataAttributes","reflexElementAttributes","elementDataset","datasetAll","elementAttributes","keys","key","isArray","startsWith","isolationMode","IsolationMode","invokeLifecycleMethod","stage","reflexElement","reflexData","reflexController","reflexMethodName","specificLifecycleMethodName","specificLifecycleMethod","genericLifecycleMethodName","genericLifecycleMethod","call","reflexError","finalStage","Reflect","deleteProperty","addEventListener","dispatchLifecycleEvent","warned","action","localReflexControllers","app","getAttribute","getControllerForElementAndIdentifier","StimulusReflex","allReflexControllers","controllers","parentElement","findControllerByReflexName","reflexName","find","identifier","received","cableReady","version","CableReady","reflexOperations","operations","splice","some","url","location","href","xpathController","xpathElement","registerReflex","pendingOperations","piggybackOperations","perform","Promise","resolve","reject","catch","getReflexRoots","list","reflexRoot","selectors","s","closest","setupDeclarativeReflexes","reflexAttributeNames","actions","controllerValue","actionValue","setAttribute","ReflexData","constructor","permanentAttributeName","tabId","_attrs","_reflexId","_selectors","resolveLate","_dataset","innerHTML","includeInnerHtml","textContent","includeTextContent","formSelector","reflexFormSelector","undefined","reflexIncludeInnerHtml","reflexIncludeTextContent","reflexSuppressLogging","valueOf","inner_html","text_content","consumer","params","subscriptionActive","createSubscription","createConsumer","channel","subscription","JSON","stringify","subscriptions","findAll","create","connected","rejected","disconnected","classList","willAttemptReconnect","ActionCableTransport","consumerValue","paramsValue","beforeDOMUpdate","afterDOMUpdate","routeReflexEvent","eventType","nothing","StimulusReflexController","Controller","super","register","initialize","isolate","remove","add","once","observer","MutationObserver","observe","documentElement","attributeFilter","childList","subtree","assign","isActionCableConnectionOpen","connection","isOpen","stimulate","arguments","shift","Node","ELEMENT_NODE","validity","badInput","opts","reflexPermanent","check","reflexSerializeForm","send","context","scope","__perform","preventDefault","stopPropagation","useReflex","global"],"mappings":"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"}
@@ -27,7 +27,26 @@ class StimulusReflex::Channel < StimulusReflex.configuration.parent_channel.cons
27
27
  reflex.logger&.error error_message
28
28
  reflex.error data: data, body: "#{exception} #{exception.backtrace.first.split(":in ")[0] if Rails.env.development?}"
29
29
  else
30
- StimulusReflex.config.logger.error error_message
30
+ if exception.is_a? StimulusReflex::Reflex::VersionMismatchError
31
+ mismatch = "Reflex failed due to stimulus_reflex gem/NPM package version mismatch. Package versions must match exactly.\nNote that if you are using pre-release builds, gems use the \"x.y.z.preN\" version format, while NPM packages use \"x.y.z-preN\".\n\nstimulus_reflex gem: #{StimulusReflex::VERSION}\nstimulus_reflex NPM: #{data["version"]}"
32
+
33
+ StimulusReflex.config.logger.error("\n\e[31m#{mismatch}\e[0m") unless StimulusReflex.config.on_failed_sanity_checks == :ignore
34
+
35
+ if Rails.env.development?
36
+ CableReady::Channels.instance[stream_name].console_log(
37
+ message: mismatch,
38
+ level: "error",
39
+ reflex_id: data["reflexId"]
40
+ ).broadcast
41
+ end
42
+
43
+ if StimulusReflex.config.on_failed_sanity_checks == :exit
44
+ sleep 0.1
45
+ exit!
46
+ end
47
+ else
48
+ StimulusReflex.config.logger.error error_message
49
+ end
31
50
 
32
51
  if body.to_s.include? "No route matches"
33
52
  initializer_path = Rails.root.join("config", "initializers", "stimulus_reflex.rb")
@@ -0,0 +1,29 @@
1
+ require "rails/engine"
2
+
3
+ module StimulusReflex
4
+ class Engine < ::Rails::Engine
5
+ initializer "stimulus_reflex.sanity_check" do
6
+ SanityChecker.check! unless Rails.env.production?
7
+ end
8
+
9
+ initializer "stimulus_reflex.assets" do |app|
10
+ if app.config.respond_to?(:assets)
11
+ app.config.assets.precompile += %w[
12
+ stimulus_reflex.js
13
+ stimulus_reflex.min.js
14
+ stimulus_reflex.min.js.map
15
+ stimulus_reflex.umd.js
16
+ stimulus_reflex.umd.min.js
17
+ stimulus_reflex.umd.min.js.map
18
+ ]
19
+ end
20
+ end
21
+
22
+ initializer "stimulus_reflex.importmap", before: "importmap" do |app|
23
+ if app.config.respond_to?(:importmap)
24
+ app.config.importmap.paths << Engine.root.join("lib/stimulus_reflex/importmap.rb")
25
+ app.config.importmap.cache_sweepers << Engine.root.join("app/assets/javascripts")
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,4 @@
1
+ pin "@rails/actioncable", to: "actioncable.esm.js", preload: true
2
+ pin "@hotwired/stimulus", to: "stimulus.min.js", preload: true
3
+ pin "cable_ready", to: "cable_ready.min.js", preload: true
4
+ pin "stimulus_reflex", to: "stimulus_reflex.min.js", preload: true
@@ -0,0 +1,29 @@
1
+ #
2
+ # Temporary fix until this PR gets merged:
3
+ # https://github.com/ruby/ostruct/pull/37
4
+ # Thanks to @Laykou
5
+ #
6
+ # Calling this in OpenStruct 0.5.2 fails:
7
+ # os = OpenStruct.new(class: "my-class", method: "post")
8
+
9
+ if defined?(OpenStruct::VERSION) && OpenStruct::VERSION == "0.5.2"
10
+ class OpenStruct
11
+ private def is_method_protected!(name)
12
+ if !respond_to?(name, true)
13
+ false
14
+ elsif name.match?(/!$/)
15
+ true
16
+ else
17
+ owner = method!(name).owner
18
+ if owner.instance_of?(::Class)
19
+ owner < ::OpenStruct
20
+ else
21
+ class!.ancestors.any? do |mod|
22
+ return false if mod == ::OpenStruct
23
+ mod == owner
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -1,8 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- ClientAttributes = Struct.new(:reflex_id, :tab_id, :reflex_controller, :xpath_controller, :xpath_element, :permanent_attribute_name, :suppress_logging, keyword_init: true)
3
+ ClientAttributes = Struct.new(:reflex_id, :tab_id, :reflex_controller, :xpath_controller, :xpath_element, :permanent_attribute_name, :version, :suppress_logging, keyword_init: true)
4
4
 
5
5
  class StimulusReflex::Reflex
6
+ class VersionMismatchError < StandardError; end
7
+
6
8
  include ActiveSupport::Rescuable
7
9
  include StimulusReflex::Callbacks
8
10
  include ActionView::Helpers::TagHelper
@@ -16,7 +18,7 @@ class StimulusReflex::Reflex
16
18
  delegate :connection, :stream_name, to: :channel
17
19
  delegate :controller_class, :flash, :session, to: :request
18
20
  delegate :broadcast, :halted, :error, to: :broadcaster
19
- delegate :reflex_id, :tab_id, :reflex_controller, :xpath_controller, :xpath_element, :permanent_attribute_name, :suppress_logging, to: :client_attributes
21
+ delegate :reflex_id, :tab_id, :reflex_controller, :xpath_controller, :xpath_element, :permanent_attribute_name, :version, :suppress_logging, to: :client_attributes
20
22
 
21
23
  def initialize(channel, url: nil, element: nil, selectors: [], method_name: nil, params: {}, client_attributes: {})
22
24
  if is_a? CableReady::Broadcaster
@@ -42,6 +44,11 @@ class StimulusReflex::Reflex
42
44
  @cable_ready = StimulusReflex::CableReadyChannels.new(stream_name, reflex_id)
43
45
  @payload = {}
44
46
  @headers = {}
47
+
48
+ if version != StimulusReflex::VERSION && StimulusReflex.config.on_failed_sanity_checks != :ignore
49
+ raise VersionMismatchError.new("stimulus_reflex gem / NPM package version mismatch")
50
+ end
51
+
45
52
  self.params
46
53
  end
47
54
 
@@ -73,6 +73,10 @@ class StimulusReflex::ReflexData
73
73
  data["reflexController"]
74
74
  end
75
75
 
76
+ def version
77
+ data["version"].gsub("-pre", ".pre")
78
+ end
79
+
76
80
  private
77
81
 
78
82
  def object_with_indifferent_access(object)
@@ -17,7 +17,8 @@ class StimulusReflex::ReflexFactory
17
17
  xpath_element: reflex_data.xpath_element,
18
18
  reflex_controller: reflex_data.reflex_controller,
19
19
  permanent_attribute_name: reflex_data.permanent_attribute_name,
20
- suppress_logging: reflex_data.suppress_logging
20
+ suppress_logging: reflex_data.suppress_logging,
21
+ version: reflex_data.version
21
22
  })
22
23
  end
23
24
 
@@ -27,6 +27,8 @@ module StimulusReflex
27
27
  def config_logging
28
28
  return @config_logging if @config_logging
29
29
 
30
+ return unless StimulusReflex.config.logging.instance_of?(Proc)
31
+
30
32
  StimulusReflex.config.logging.binding.eval("using StimulusReflex::Utils::Colorize")
31
33
  @config_logging = StimulusReflex.config.logging
32
34
  end
@@ -2,8 +2,6 @@
2
2
 
3
3
  class StimulusReflex::SanityChecker
4
4
  LATEST_VERSION_FORMAT = /^(\d+\.\d+\.\d+)$/
5
- NODE_VERSION_FORMAT = /(\d+\.\d+\.\d+.*):/
6
- JSON_VERSION_FORMAT = /(\d+\.\d+\.\d+.*)"/
7
5
 
8
6
  class << self
9
7
  def check!
@@ -15,7 +13,6 @@ class StimulusReflex::SanityChecker
15
13
 
16
14
  instance = new
17
15
  instance.check_caching_enabled
18
- instance.check_package_versions_match
19
16
  # instance.check_default_url_config
20
17
  instance.check_new_version_available
21
18
  end
@@ -73,28 +70,6 @@ class StimulusReflex::SanityChecker
73
70
  end
74
71
  end
75
72
 
76
- def check_package_versions_match
77
- if npm_version.nil?
78
- warn_and_exit <<~WARN
79
- 👉 Can't locate the stimulus_reflex npm package.
80
-
81
- yarn add stimulus_reflex@#{gem_version}
82
-
83
- Either add it to your package.json as a dependency or use "yarn link stimulus_reflex" if you are doing development.
84
- WARN
85
- end
86
-
87
- if package_version_mismatch?
88
- warn_and_exit <<~WARN
89
- 👉 The stimulus_reflex npm package version (#{npm_version}) does not match the Rubygem version (#{gem_version}).
90
-
91
- To update the stimulus_reflex npm package:
92
-
93
- yarn upgrade stimulus_reflex@#{gem_version}
94
- WARN
95
- end
96
- end
97
-
98
73
  def check_new_version_available
99
74
  return if StimulusReflex.config.on_new_version_available == :ignore
100
75
  return if Rails.env.development? == false
@@ -134,45 +109,12 @@ class StimulusReflex::SanityChecker
134
109
  end
135
110
  end
136
111
 
137
- def package_version_mismatch?
138
- npm_version != gem_version
139
- end
140
-
141
112
  def using_preview_release?
142
113
  preview = StimulusReflex::VERSION.match?(LATEST_VERSION_FORMAT) == false
143
114
  puts "👉 StimulusReflex #{StimulusReflex::VERSION} update check skipped: pre-release build" if preview
144
115
  preview
145
116
  end
146
117
 
147
- def gem_version
148
- @_gem_version ||= StimulusReflex::VERSION.gsub(".pre", "-pre")
149
- end
150
-
151
- def npm_version
152
- @_npm_version ||= find_npm_version
153
- end
154
-
155
- def find_npm_version
156
- if (match = search_file(package_json_path, regex: /version/))
157
- match[JSON_VERSION_FORMAT, 1]
158
- elsif (match = search_file(yarn_lock_path, regex: /^stimulus_reflex/))
159
- match[NODE_VERSION_FORMAT, 1]
160
- end
161
- end
162
-
163
- def search_file(path, regex:)
164
- return if File.exist?(path) == false
165
- File.foreach(path).grep(regex).first
166
- end
167
-
168
- def package_json_path
169
- Rails.root.join("node_modules", "stimulus_reflex", "package.json")
170
- end
171
-
172
- def yarn_lock_path
173
- Rails.root.join("yarn.lock")
174
- end
175
-
176
118
  def initializer_missing?
177
119
  File.exist?(Rails.root.join("config", "initializers", "stimulus_reflex.rb")) == false
178
120
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module StimulusReflex
4
- VERSION = "3.5.0.pre8"
4
+ VERSION = "3.5.0.pre9"
5
5
  end
@@ -3,7 +3,6 @@
3
3
  require "uri"
4
4
  require "open-uri"
5
5
  require "rack"
6
- require "rails/engine"
7
6
  require "active_support/all"
8
7
  require "action_dispatch"
9
8
  require "action_cable"
@@ -11,6 +10,7 @@ require "action_view"
11
10
  require "nokogiri"
12
11
  require "cable_ready"
13
12
  require "stimulus_reflex/version"
13
+ require "stimulus_reflex/open_struct_fix"
14
14
  require "stimulus_reflex/cable_ready_channels"
15
15
  require "stimulus_reflex/concern_enhancer"
16
16
  require "stimulus_reflex/configuration"
@@ -20,6 +20,7 @@ require "stimulus_reflex/reflex"
20
20
  require "stimulus_reflex/reflex_data"
21
21
  require "stimulus_reflex/reflex_factory"
22
22
  require "stimulus_reflex/element"
23
+ require "stimulus_reflex/engine"
23
24
  require "stimulus_reflex/broadcasters/broadcaster"
24
25
  require "stimulus_reflex/broadcasters/nothing_broadcaster"
25
26
  require "stimulus_reflex/broadcasters/page_broadcaster"
@@ -31,9 +32,4 @@ require "stimulus_reflex/utils/logger"
31
32
  require "stimulus_reflex/utils/sanity_checker"
32
33
 
33
34
  module StimulusReflex
34
- class Engine < Rails::Engine
35
- initializer "stimulus_reflex.sanity_check" do
36
- SanityChecker.check! unless Rails.env.production?
37
- end
38
- end
39
35
  end
data/package.json ADDED
@@ -0,0 +1,67 @@
1
+ {
2
+ "name": "stimulus_reflex",
3
+ "version": "3.5.0-pre9",
4
+ "description": "Build reactive applications with the Rails tooling you already know and love.",
5
+ "keywords": [
6
+ "ruby",
7
+ "rails",
8
+ "websockets",
9
+ "actioncable",
10
+ "turbolinks",
11
+ "reactive",
12
+ "cable",
13
+ "ujs",
14
+ "ssr",
15
+ "stimulus",
16
+ "reflex",
17
+ "stimulus_reflex",
18
+ "dom",
19
+ "morphdom"
20
+ ],
21
+ "homepage": "https://docs.stimulusreflex.com/",
22
+ "bugs": {
23
+ "url": "https://github.com/stimulusreflex/stimulus_reflex/issues"
24
+ },
25
+ "repository": {
26
+ "type": "git",
27
+ "url": "git+https://github.com:stimulusreflex/stimulus_reflex.git"
28
+ },
29
+ "license": "MIT",
30
+ "author": "Nathan Hopkins <natehop@gmail.com>",
31
+ "main": "./dist/stimulus_reflex.umd.min.js",
32
+ "module": "./dist/stimulus_reflex.min.js",
33
+ "files": [
34
+ "dist/*",
35
+ "javascript/*"
36
+ ],
37
+ "scripts": {
38
+ "lint": "yarn prettier-standard:check",
39
+ "format": "yarn prettier-standard:format",
40
+ "build": "yarn rollup -c",
41
+ "build:watch": "yarn rollup -wc",
42
+ "watch": "yarn build:watch",
43
+ "prettier-standard:check": "yarn run prettier-standard --check ./javascript/**/*.js rollup.config.js",
44
+ "prettier-standard:format": "yarn run prettier-standard ./javascript/**/*.js rollup.config.js",
45
+ "test": "web-test-runner javascript/test/**/*.test.js"
46
+ },
47
+ "peerDependencies": {
48
+ "@hotwired/stimulus": ">= 3.0"
49
+ },
50
+ "dependencies": {
51
+ "@hotwired/stimulus": ">= 3.0",
52
+ "@rails/actioncable": ">= 6.0",
53
+ "cable_ready": ">= 5.0.0-pre9"
54
+ },
55
+ "devDependencies": {
56
+ "@open-wc/testing": "^3.1.2",
57
+ "@rollup/plugin-commonjs": "^21.0.3",
58
+ "@rollup/plugin-json": "^4.1.0",
59
+ "@rollup/plugin-node-resolve": "^13.1.3",
60
+ "@web/dev-server-esbuild": "^0.3.0",
61
+ "@web/dev-server-rollup": "^0.3.15",
62
+ "@web/test-runner": "^0.13.27",
63
+ "prettier-standard": "^16.4.1",
64
+ "rollup": "^2.70.1",
65
+ "rollup-plugin-terser": "^7.0.2"
66
+ }
67
+ }
data/rollup.config.js ADDED
@@ -0,0 +1,85 @@
1
+ import resolve from '@rollup/plugin-node-resolve'
2
+ import commonjs from '@rollup/plugin-commonjs'
3
+ import json from '@rollup/plugin-json'
4
+ import { terser } from 'rollup-plugin-terser'
5
+
6
+ const pretty = () => {
7
+ return terser({
8
+ mangle: false,
9
+ compress: false,
10
+ format: {
11
+ beautify: true,
12
+ indent_level: 2
13
+ }
14
+ })
15
+ }
16
+
17
+ const minify = () => {
18
+ return terser({
19
+ mangle: true,
20
+ compress: true
21
+ })
22
+ }
23
+
24
+ const esConfig = {
25
+ format: 'es',
26
+ inlineDynamicImports: true
27
+ }
28
+
29
+ const umdConfig = {
30
+ name: 'StimulusReflex',
31
+ format: 'umd',
32
+ exports: 'named',
33
+ globals: {
34
+ morphdom: 'morphdom',
35
+ cable_ready: 'CableReady',
36
+ '@hotwired/stimulus': 'Stimulus'
37
+ }
38
+ }
39
+
40
+ const distFolders = ['dist', 'app/assets/javascripts']
41
+
42
+ const output = distFolders
43
+ .map(distFolder => [
44
+ {
45
+ ...umdConfig,
46
+ file: `${distFolder}/stimulus_reflex.umd.js`,
47
+ plugins: [pretty()]
48
+ },
49
+ {
50
+ ...umdConfig,
51
+ file: `${distFolder}/stimulus_reflex.umd.min.js`,
52
+ sourcemap: true,
53
+ plugins: [pretty()]
54
+ },
55
+ {
56
+ ...esConfig,
57
+ file: `${distFolder}/stimulus_reflex.js`,
58
+ format: 'es',
59
+ plugins: [pretty()]
60
+ },
61
+ {
62
+ ...esConfig,
63
+ file: `${distFolder}/stimulus_reflex.min.js`,
64
+ sourcemap: true,
65
+ plugins: [minify()]
66
+ }
67
+ ])
68
+ .flat()
69
+
70
+ export default [
71
+ {
72
+ external: [
73
+ 'morphdom',
74
+ '@hotwired/stimulus',
75
+ 'cable_ready',
76
+ '@rails/actioncable'
77
+ ],
78
+ input: 'javascript/index.js',
79
+ output,
80
+ plugins: [commonjs(), resolve(), json()],
81
+ watch: {
82
+ include: 'javascript/**'
83
+ }
84
+ }
85
+ ]