mobility-toolbox-js 2.3.9 → 2.3.10

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.
Files changed (471) hide show
  1. package/.esdoc.js +18 -0
  2. package/.eslintignore +1 -0
  3. package/.eslintrc.js +25 -0
  4. package/.fixpackrc +20 -0
  5. package/.github/workflows/build.yml +16 -0
  6. package/.github/workflows/conventional-pr-title.yml +16 -0
  7. package/.github/workflows/cypress.yml +101 -0
  8. package/.github/workflows/test.yml +17 -0
  9. package/.husky/commit-msg +4 -0
  10. package/.husky/post-checkout +4 -0
  11. package/.husky/post-merge +4 -0
  12. package/.husky/post-rebase +4 -0
  13. package/.husky/pre-commit +4 -0
  14. package/.lintstagedrc.js +10 -0
  15. package/.nvmrc +1 -0
  16. package/.prettierrc.js +5 -0
  17. package/.stylelintrc.js +4 -0
  18. package/CHANGELOG.md +132 -0
  19. package/LICENSE +21 -0
  20. package/MIGRATION-V2.md +248 -0
  21. package/README.md +42 -0
  22. package/__mocks__/mapbox-gl.js +81 -0
  23. package/__mocks__/maplibre-gl.js +81 -0
  24. package/babel.config.js +9 -0
  25. package/commitlint.config.js +1 -0
  26. package/cypress/e2e/examples/api.cy.js +7 -0
  27. package/cypress/e2e/examples/examples.cy.js +7 -0
  28. package/cypress/e2e/examples/navigation.cy.js +29 -0
  29. package/cypress/fixtures/example.json +5 -0
  30. package/cypress/plugins/index.js +21 -0
  31. package/cypress/support/commands.js +25 -0
  32. package/cypress/support/e2e.js +20 -0
  33. package/cypress.config.ts +15 -0
  34. package/data/fetchRoute.json +292 -0
  35. package/data/fetchTrajectories.json +18 -0
  36. package/data/fetchTrajectoryById.json +3 -0
  37. package/data/fetchTrajectoryStations.json +18 -0
  38. package/data/stopsSearch.json +15 -0
  39. package/dependabot.yml +15 -0
  40. package/doc/.eslintrc.json +1 -0
  41. package/doc/README.md +34 -0
  42. package/doc/next.config.js +16 -0
  43. package/doc/package.json +41 -0
  44. package/doc/pages/404.js +5 -0
  45. package/doc/pages/_app.js +61 -0
  46. package/doc/pages/_document.js +64 -0
  47. package/doc/pages/doc/[...slug].js +23 -0
  48. package/doc/pages/doc.js +23 -0
  49. package/doc/pages/example/[example].js +52 -0
  50. package/doc/pages/examples.js +34 -0
  51. package/doc/pages/index.js +25 -0
  52. package/doc/public/README.md +15 -0
  53. package/doc/public/favicon.ico +0 -0
  54. package/doc/public/static/assets/Lato-Black.ttf +0 -0
  55. package/doc/public/static/assets/Lato-BlackItalic.ttf +0 -0
  56. package/doc/public/static/assets/Lato-Bold.ttf +0 -0
  57. package/doc/public/static/assets/Lato-BoldItalic.ttf +0 -0
  58. package/doc/public/static/assets/Lato-Italic.ttf +0 -0
  59. package/doc/public/static/assets/Lato-Light.ttf +0 -0
  60. package/doc/public/static/assets/Lato-LightItalic.ttf +0 -0
  61. package/doc/public/static/assets/Lato-Regular.ttf +0 -0
  62. package/doc/public/static/assets/Lato-Thin.ttf +0 -0
  63. package/doc/public/static/assets/Lato-ThinItalic.ttf +0 -0
  64. package/doc/public/static/assets/OFL.txt +93 -0
  65. package/doc/public/static/examples/assets/tralis-live-map/index.js +11 -0
  66. package/doc/public/static/examples/assets/tralis-live-map/s1kreis.svg +105 -0
  67. package/doc/public/static/examples/assets/tralis-live-map/s20kreis.svg +101 -0
  68. package/doc/public/static/examples/assets/tralis-live-map/s2kreis.svg +95 -0
  69. package/doc/public/static/examples/assets/tralis-live-map/s3kreis.svg +95 -0
  70. package/doc/public/static/examples/assets/tralis-live-map/s4kreis.svg +95 -0
  71. package/doc/public/static/examples/assets/tralis-live-map/s6kreis.svg +95 -0
  72. package/doc/public/static/examples/assets/tralis-live-map/s7kreis.svg +95 -0
  73. package/doc/public/static/examples/assets/tralis-live-map/s8kreis.svg +93 -0
  74. package/doc/public/static/examples/assets/tralis-live-map/unknown.svg +107 -0
  75. package/doc/public/static/examples/layers.html +11 -0
  76. package/doc/public/static/examples/layers.js +97 -0
  77. package/doc/public/static/examples/mb-copyright.html +26 -0
  78. package/doc/public/static/examples/mb-copyright.js +37 -0
  79. package/doc/public/static/examples/mb-tracker.html +1 -0
  80. package/doc/public/static/examples/mb-tracker.js +40 -0
  81. package/doc/public/static/examples/mb-tracker.md +1 -0
  82. package/doc/public/static/examples/mb-tralis.html +1 -0
  83. package/doc/public/static/examples/mb-tralis.js +34 -0
  84. package/doc/public/static/examples/ol-copyright.html +26 -0
  85. package/doc/public/static/examples/ol-copyright.js +43 -0
  86. package/doc/public/static/examples/ol-mapbox-layer.html +1 -0
  87. package/doc/public/static/examples/ol-mapbox-layer.js +28 -0
  88. package/doc/public/static/examples/ol-mapbox-style-layer.html +12 -0
  89. package/doc/public/static/examples/ol-mapbox-style-layer.js +48 -0
  90. package/doc/public/static/examples/ol-query.html +32 -0
  91. package/doc/public/static/examples/ol-query.js +83 -0
  92. package/doc/public/static/examples/ol-routing.html +26 -0
  93. package/doc/public/static/examples/ol-routing.js +65 -0
  94. package/doc/public/static/examples/ol-routing.md +1 -0
  95. package/doc/public/static/examples/ol-stop-finder.html +15 -0
  96. package/doc/public/static/examples/ol-stop-finder.js +35 -0
  97. package/doc/public/static/examples/ol-stop-finder.md +1 -0
  98. package/doc/public/static/examples/ol-tracker.html +1 -0
  99. package/doc/public/static/examples/ol-tracker.js +41 -0
  100. package/doc/public/static/examples/ol-tracker.md +1 -0
  101. package/doc/public/static/examples/ol-tralis.html +5 -0
  102. package/doc/public/static/examples/ol-tralis.js +62 -0
  103. package/doc/public/static/examples/tralis-live-map.html +1 -0
  104. package/doc/public/static/examples/tralis-live-map.js +67 -0
  105. package/doc/public/static/examples/tralis-live-map.md +3 -0
  106. package/doc/public/static/img/live_tracker_mb.jpg +0 -0
  107. package/doc/public/static/img/live_tracker_munich.jpg +0 -0
  108. package/doc/public/static/img/live_tracker_ol.jpg +0 -0
  109. package/doc/public/static/img/mapbox.jpg +0 -0
  110. package/doc/public/static/img/mapbox_style.jpg +0 -0
  111. package/doc/public/static/img/ol-copyright.png +0 -0
  112. package/doc/public/static/img/query_objects.jpg +0 -0
  113. package/doc/public/static/img/routing.jpg +0 -0
  114. package/doc/public/static/img/simple_map.jpg +0 -0
  115. package/doc/public/static/img/stops.jpg +0 -0
  116. package/doc/public/vercel.svg +4 -0
  117. package/doc/src/components/CodeSandboxButton.js +102 -0
  118. package/doc/src/components/Documentation.js +42 -0
  119. package/doc/src/components/Esdoc/Anchor.js +57 -0
  120. package/doc/src/components/Esdoc/ClassDoc.js +272 -0
  121. package/doc/src/components/Esdoc/DeprecatedHTML.js +16 -0
  122. package/doc/src/components/Esdoc/DetailDocs.js +279 -0
  123. package/doc/src/components/Esdoc/DetailHTML.js +33 -0
  124. package/doc/src/components/Esdoc/DirectSubclassHTML.js +30 -0
  125. package/doc/src/components/Esdoc/DocBuilderUtils.js +697 -0
  126. package/doc/src/components/Esdoc/DocLinkHTML.js +63 -0
  127. package/doc/src/components/Esdoc/DocsLinkHTML.js +38 -0
  128. package/doc/src/components/Esdoc/Esdoc.js +63 -0
  129. package/doc/src/components/Esdoc/EsdocContent.js +56 -0
  130. package/doc/src/components/Esdoc/EsdocNavigation.js +13 -0
  131. package/doc/src/components/Esdoc/EsdocSearch.js +78 -0
  132. package/doc/src/components/Esdoc/ExperimentalHTML.js +17 -0
  133. package/doc/src/components/Esdoc/ExtendsChainHTML.js +32 -0
  134. package/doc/src/components/Esdoc/FileDocLinkHTML.js +62 -0
  135. package/doc/src/components/Esdoc/IdentifiersDoc.js +113 -0
  136. package/doc/src/components/Esdoc/IndirectSubclassHTML.js +30 -0
  137. package/doc/src/components/Esdoc/InheritedSummaryDoc.js +70 -0
  138. package/doc/src/components/Esdoc/InheritedSummaryHTML.js +38 -0
  139. package/doc/src/components/Esdoc/MixinClassesHTML.js +29 -0
  140. package/doc/src/components/Esdoc/NavDoc.js +112 -0
  141. package/doc/src/components/Esdoc/OverrideMethod.js +44 -0
  142. package/doc/src/components/Esdoc/OverrideMethodDescription.js +35 -0
  143. package/doc/src/components/Esdoc/Properties.js +89 -0
  144. package/doc/src/components/Esdoc/README.md +45 -0
  145. package/doc/src/components/Esdoc/SignatureHTML.js +123 -0
  146. package/doc/src/components/Esdoc/SingleDoc.js +31 -0
  147. package/doc/src/components/Esdoc/SummaryDoc.js +160 -0
  148. package/doc/src/components/Esdoc/SummaryHTML.js +96 -0
  149. package/doc/src/components/Esdoc/TypeDocLinkHTML.js +251 -0
  150. package/doc/src/components/Esdoc/index.js +7 -0
  151. package/doc/src/components/Esdoc/taffydb.js +2070 -0
  152. package/doc/src/components/Example.js +200 -0
  153. package/doc/src/components/ExampleCard.js +126 -0
  154. package/doc/src/components/Examples.js +78 -0
  155. package/doc/src/components/Home.js +121 -0
  156. package/doc/src/components/TrackerExample.js +39 -0
  157. package/doc/src/examples.js +117 -0
  158. package/doc/styles/App.scss +53 -0
  159. package/doc/styles/identifiers.css +38 -0
  160. package/doc/styles/search.css +76 -0
  161. package/doc/styles/style.css +603 -0
  162. package/esdoc/README.md +27 -0
  163. package/esdoc/plugins/MyPlugin.js +69 -0
  164. package/esdoc/plugins/dynamic-property-plugin/Plugin.js +50 -0
  165. package/esdoc/plugins/externals-plugin/Plugin.js +45 -0
  166. package/esdoc/plugins/externals-plugin/externals.js +93 -0
  167. package/esdoc/plugins/optional-chaining-plugin/Plugin.js +8 -0
  168. package/global-setup.js +3 -0
  169. package/jest.config.js +24 -0
  170. package/package.json +18 -18
  171. package/pull_request_template.md +17 -0
  172. package/scripts/read-pkg-json.js +22 -0
  173. package/src/api/RealtimeAPI.test.js +144 -0
  174. package/src/api/RealtimeAPI.ts +712 -0
  175. package/src/api/RoutingAPI.test.js +41 -0
  176. package/src/api/RoutingAPI.ts +47 -0
  177. package/src/api/StopsAPI.test.js +34 -0
  178. package/src/api/StopsAPI.ts +45 -0
  179. package/{api → src/api}/typedefs.js +11 -1
  180. package/src/common/api/HttpAPI.test.js +68 -0
  181. package/src/common/api/HttpAPI.ts +77 -0
  182. package/src/common/api/WebSocketAPI.test.js +421 -0
  183. package/src/common/api/WebSocketAPI.ts +515 -0
  184. package/src/common/controls/ControlCommon.test.js +106 -0
  185. package/src/common/controls/ControlCommon.ts +194 -0
  186. package/src/common/controls/CopyrightControlCommon.ts +41 -0
  187. package/src/common/controls/StopFinderControlCommon.ts +192 -0
  188. package/src/common/layers/LayerCommon.test.js +158 -0
  189. package/src/common/layers/LayerCommon.ts +321 -0
  190. package/src/common/mixins/RealtimeLayerMixin.ts +1168 -0
  191. package/src/common/mixins/UserInteractionsLayerMixin.test.js +227 -0
  192. package/src/common/mixins/UserInteractionsLayerMixin.ts +352 -0
  193. package/src/common/styles/realtimeDefaultStyle.ts +436 -0
  194. package/src/common/styles/realtimeDelayStyle.ts +27 -0
  195. package/src/common/styles/realtimeHeadingStyle.ts +138 -0
  196. package/src/common/styles/realtimeSimpleStyle.ts +25 -0
  197. package/{common → src/common}/typedefs.js +1 -1
  198. package/src/common/utils/compareDepartures.ts +46 -0
  199. package/src/common/utils/createCanvas.ts +33 -0
  200. package/src/common/utils/createRealtimeFilters.test.js +100 -0
  201. package/src/common/utils/createRealtimeFilters.ts +96 -0
  202. package/src/common/utils/debounceDeparturesMessages.ts +52 -0
  203. package/src/common/utils/debounceWebsocketMessages.ts +47 -0
  204. package/src/common/utils/getLayersAsFlatArray.ts +17 -0
  205. package/src/common/utils/getMapboxMapCopyrights.test.js +47 -0
  206. package/src/common/utils/getMapboxMapCopyrights.ts +52 -0
  207. package/src/common/utils/getMapboxRender.ts +104 -0
  208. package/src/common/utils/getMaplibreRender.ts +54 -0
  209. package/{common/utils/getRealtimeModeSuffix.d.ts → src/common/utils/getRealtimeModeSuffix.ts} +4 -2
  210. package/src/common/utils/getUrlWithParams.ts +21 -0
  211. package/src/common/utils/getVehiclePosition.ts +92 -0
  212. package/{common → src/common}/utils/index.js +1 -2
  213. package/src/common/utils/realtimeConfig.test.js +57 -0
  214. package/src/common/utils/realtimeConfig.ts +228 -0
  215. package/src/common/utils/removeDuplicate.test.js +22 -0
  216. package/src/common/utils/removeDuplicate.ts +22 -0
  217. package/src/common/utils/renderTrajectories.ts +194 -0
  218. package/src/common/utils/sortAndFilterDepartures.ts +78 -0
  219. package/src/common/utils/sortByDelay.ts +29 -0
  220. package/src/common/utils/timeUtils.test.js +16 -0
  221. package/src/common/utils/timeUtils.ts +45 -0
  222. package/{iife.js → src/iife.js} +3 -1
  223. package/src/index.js +10 -0
  224. package/{mapbox/controls/CopyrightControl.js → src/mapbox/controls/CopyrightControl.ts} +26 -21
  225. package/src/mapbox/layers/Layer.test.js +217 -0
  226. package/src/mapbox/layers/Layer.ts +144 -0
  227. package/src/mapbox/layers/RealtimeLayer.test.js +13 -0
  228. package/src/mapbox/layers/RealtimeLayer.ts +350 -0
  229. package/src/mapbox/utils/getMercatorResolution.ts +21 -0
  230. package/src/mapbox/utils/getSourceCoordinates.ts +34 -0
  231. package/src/ol/README.md +0 -0
  232. package/src/ol/controls/CopyrightControl.test.js +211 -0
  233. package/src/ol/controls/CopyrightControl.ts +82 -0
  234. package/src/ol/controls/RoutingControl.test.js +205 -0
  235. package/src/ol/controls/RoutingControl.ts +869 -0
  236. package/src/ol/controls/StopFinderControl.test.js +59 -0
  237. package/{ol/controls/StopFinderControl.js → src/ol/controls/StopFinderControl.ts} +10 -7
  238. package/src/ol/controls/snapshots/RoutingControlRouteGen10.json +58 -0
  239. package/src/ol/controls/snapshots/RoutingControlRouteGen100.json +292 -0
  240. package/src/ol/controls/snapshots/RoutingControlRouteGen30.json +69 -0
  241. package/src/ol/controls/snapshots/RoutingControlRouteGen5.json +58 -0
  242. package/src/ol/controls/snapshots/RoutingControlRouteOSM.json +759 -0
  243. package/src/ol/controls/snapshots/RoutingControlStation1.json +60 -0
  244. package/src/ol/controls/snapshots/RoutingControlStation2.json +49 -0
  245. package/src/ol/layers/Layer.test.js +212 -0
  246. package/src/ol/layers/Layer.ts +252 -0
  247. package/src/ol/layers/MapGlLayer.ts +294 -0
  248. package/src/ol/layers/MapboxLayer.test.js +190 -0
  249. package/src/ol/layers/MapboxLayer.ts +136 -0
  250. package/src/ol/layers/MapboxStyleLayer.test.js +258 -0
  251. package/src/ol/layers/MapboxStyleLayer.ts +466 -0
  252. package/{ol/layers/MaplibreLayer.d.ts → src/ol/layers/MaplibreLayer.ts} +21 -10
  253. package/src/ol/layers/RealtimeLayer.test.js +84 -0
  254. package/src/ol/layers/RealtimeLayer.ts +465 -0
  255. package/src/ol/layers/RoutingLayer.test.js +48 -0
  256. package/src/ol/layers/RoutingLayer.ts +113 -0
  257. package/src/ol/layers/VectorLayer.test.js +87 -0
  258. package/src/ol/layers/VectorLayer.ts +48 -0
  259. package/src/ol/layers/WMSLayer.test.js +65 -0
  260. package/src/ol/layers/WMSLayer.ts +114 -0
  261. package/src/ol/styles/fullTrajectoryDelayStyle.ts +37 -0
  262. package/src/ol/styles/fullTrajectoryStyle.ts +56 -0
  263. package/{setupTests.js → src/setupTests.js} +12 -7
  264. package/tsconfig.json +23 -0
  265. package/api/RealtimeAPI.d.ts +0 -290
  266. package/api/RealtimeAPI.d.ts.map +0 -1
  267. package/api/RealtimeAPI.js +0 -483
  268. package/api/RoutingAPI.d.ts +0 -37
  269. package/api/RoutingAPI.d.ts.map +0 -1
  270. package/api/RoutingAPI.js +0 -35
  271. package/api/StopsAPI.d.ts +0 -38
  272. package/api/StopsAPI.d.ts.map +0 -1
  273. package/api/StopsAPI.js +0 -36
  274. package/api/index.d.ts +0 -4
  275. package/api/index.d.ts.map +0 -1
  276. package/api/typedefs.d.ts +0 -179
  277. package/api/typedefs.d.ts.map +0 -1
  278. package/common/api/HttpAPI.d.ts +0 -31
  279. package/common/api/HttpAPI.d.ts.map +0 -1
  280. package/common/api/HttpAPI.js +0 -57
  281. package/common/api/WebSocketAPI.d.ts +0 -153
  282. package/common/api/WebSocketAPI.d.ts.map +0 -1
  283. package/common/api/WebSocketAPI.js +0 -341
  284. package/common/controls/ControlCommon.d.ts +0 -76
  285. package/common/controls/ControlCommon.d.ts.map +0 -1
  286. package/common/controls/ControlCommon.js +0 -150
  287. package/common/controls/CopyrightControlCommon.d.ts +0 -13
  288. package/common/controls/CopyrightControlCommon.d.ts.map +0 -1
  289. package/common/controls/CopyrightControlCommon.js +0 -34
  290. package/common/controls/StopFinderControlCommon.d.ts +0 -55
  291. package/common/controls/StopFinderControlCommon.d.ts.map +0 -1
  292. package/common/controls/StopFinderControlCommon.js +0 -144
  293. package/common/index.d.ts +0 -3
  294. package/common/index.d.ts.map +0 -1
  295. package/common/layers/LayerCommon.d.ts +0 -94
  296. package/common/layers/LayerCommon.d.ts.map +0 -1
  297. package/common/layers/LayerCommon.js +0 -244
  298. package/common/mixins/RealtimeLayerMixin.d.ts +0 -288
  299. package/common/mixins/RealtimeLayerMixin.d.ts.map +0 -1
  300. package/common/mixins/RealtimeLayerMixin.js +0 -779
  301. package/common/mixins/UserInteractionsLayerMixin.d.ts +0 -60
  302. package/common/mixins/UserInteractionsLayerMixin.d.ts.map +0 -1
  303. package/common/mixins/UserInteractionsLayerMixin.js +0 -241
  304. package/common/styles/index.d.ts +0 -5
  305. package/common/styles/index.d.ts.map +0 -1
  306. package/common/styles/realtimeDefaultStyle.d.ts +0 -36
  307. package/common/styles/realtimeDefaultStyle.d.ts.map +0 -1
  308. package/common/styles/realtimeDefaultStyle.js +0 -276
  309. package/common/styles/realtimeDelayStyle.d.ts +0 -12
  310. package/common/styles/realtimeDelayStyle.d.ts.map +0 -1
  311. package/common/styles/realtimeDelayStyle.js +0 -13
  312. package/common/styles/realtimeHeadingStyle.d.ts +0 -12
  313. package/common/styles/realtimeHeadingStyle.d.ts.map +0 -1
  314. package/common/styles/realtimeHeadingStyle.js +0 -87
  315. package/common/styles/realtimeSimpleStyle.d.ts +0 -4
  316. package/common/styles/realtimeSimpleStyle.d.ts.map +0 -1
  317. package/common/styles/realtimeSimpleStyle.js +0 -23
  318. package/common/typedefs.d.ts +0 -183
  319. package/common/typedefs.d.ts.map +0 -1
  320. package/common/utils/compareDepartures.d.ts +0 -11
  321. package/common/utils/compareDepartures.d.ts.map +0 -1
  322. package/common/utils/compareDepartures.js +0 -35
  323. package/common/utils/createCanvas.d.ts +0 -11
  324. package/common/utils/createCanvas.d.ts.map +0 -1
  325. package/common/utils/createCanvas.js +0 -28
  326. package/common/utils/createRealtimeFilters.d.ts +0 -13
  327. package/common/utils/createRealtimeFilters.d.ts.map +0 -1
  328. package/common/utils/createRealtimeFilters.js +0 -74
  329. package/common/utils/debounceDeparturesMessages.d.ts +0 -13
  330. package/common/utils/debounceDeparturesMessages.d.ts.map +0 -1
  331. package/common/utils/debounceDeparturesMessages.js +0 -28
  332. package/common/utils/debounceWebsocketMessages.d.ts +0 -12
  333. package/common/utils/debounceWebsocketMessages.d.ts.map +0 -1
  334. package/common/utils/debounceWebsocketMessages.js +0 -30
  335. package/common/utils/getLayersAsFlatArray.d.ts +0 -4
  336. package/common/utils/getLayersAsFlatArray.d.ts.map +0 -1
  337. package/common/utils/getLayersAsFlatArray.js +0 -16
  338. package/common/utils/getMapboxMapCopyrights.d.ts +0 -18
  339. package/common/utils/getMapboxMapCopyrights.d.ts.map +0 -1
  340. package/common/utils/getMapboxMapCopyrights.js +0 -30
  341. package/common/utils/getMapboxRender.d.ts +0 -8
  342. package/common/utils/getMapboxRender.d.ts.map +0 -1
  343. package/common/utils/getMapboxRender.js +0 -88
  344. package/common/utils/getMaplibreRender.d.ts +0 -9
  345. package/common/utils/getMaplibreRender.d.ts.map +0 -1
  346. package/common/utils/getMaplibreRender.js +0 -40
  347. package/common/utils/getRealtimeModeSuffix.d.ts.map +0 -1
  348. package/common/utils/getRealtimeModeSuffix.js +0 -7
  349. package/common/utils/getUrlWithParams.d.ts +0 -9
  350. package/common/utils/getUrlWithParams.d.ts.map +0 -1
  351. package/common/utils/getUrlWithParams.js +0 -18
  352. package/common/utils/getVehiclePosition.d.ts +0 -16
  353. package/common/utils/getVehiclePosition.d.ts.map +0 -1
  354. package/common/utils/getVehiclePosition.js +0 -72
  355. package/common/utils/index.d.ts +0 -18
  356. package/common/utils/index.d.ts.map +0 -1
  357. package/common/utils/realtimeConfig.d.ts +0 -53
  358. package/common/utils/realtimeConfig.d.ts.map +0 -1
  359. package/common/utils/realtimeConfig.js +0 -202
  360. package/common/utils/removeDuplicate.d.ts +0 -10
  361. package/common/utils/removeDuplicate.d.ts.map +0 -1
  362. package/common/utils/removeDuplicate.js +0 -15
  363. package/common/utils/renderTrajectories.d.ts +0 -17
  364. package/common/utils/renderTrajectories.d.ts.map +0 -1
  365. package/common/utils/renderTrajectories.js +0 -110
  366. package/common/utils/sortAndFilterDepartures.d.ts +0 -16
  367. package/common/utils/sortAndFilterDepartures.d.ts.map +0 -1
  368. package/common/utils/sortAndFilterDepartures.js +0 -58
  369. package/common/utils/sortByDelay.d.ts +0 -4
  370. package/common/utils/sortByDelay.d.ts.map +0 -1
  371. package/common/utils/sortByDelay.js +0 -21
  372. package/common/utils/timeUtils.d.ts +0 -24
  373. package/common/utils/timeUtils.d.ts.map +0 -1
  374. package/common/utils/timeUtils.js +0 -39
  375. package/iife.d.ts +0 -3
  376. package/iife.d.ts.map +0 -1
  377. package/index.d.ts +0 -10
  378. package/index.d.ts.map +0 -1
  379. package/index.js +0 -10
  380. package/mapbox/controls/CopyrightControl.d.ts +0 -29
  381. package/mapbox/controls/CopyrightControl.d.ts.map +0 -1
  382. package/mapbox/controls/index.d.ts +0 -2
  383. package/mapbox/controls/index.d.ts.map +0 -1
  384. package/mapbox/index.d.ts +0 -6
  385. package/mapbox/index.d.ts.map +0 -1
  386. package/mapbox/layers/Layer.d.ts +0 -59
  387. package/mapbox/layers/Layer.d.ts.map +0 -1
  388. package/mapbox/layers/Layer.js +0 -101
  389. package/mapbox/layers/RealtimeLayer.d.ts +0 -180
  390. package/mapbox/layers/RealtimeLayer.d.ts.map +0 -1
  391. package/mapbox/layers/RealtimeLayer.js +0 -270
  392. package/mapbox/layers/index.d.ts +0 -3
  393. package/mapbox/layers/index.d.ts.map +0 -1
  394. package/mapbox/utils/getMercatorResolution.d.ts +0 -9
  395. package/mapbox/utils/getMercatorResolution.d.ts.map +0 -1
  396. package/mapbox/utils/getMercatorResolution.js +0 -18
  397. package/mapbox/utils/getSourceCoordinates.d.ts +0 -9
  398. package/mapbox/utils/getSourceCoordinates.d.ts.map +0 -1
  399. package/mapbox/utils/getSourceCoordinates.js +0 -27
  400. package/mapbox/utils/index.d.ts +0 -3
  401. package/mapbox/utils/index.d.ts.map +0 -1
  402. package/mbt.js +0 -64706
  403. package/mbt.js.map +0 -7
  404. package/mbt.min.js +0 -1090
  405. package/mbt.min.js.map +0 -7
  406. package/ol/controls/CopyrightControl.d.ts +0 -31
  407. package/ol/controls/CopyrightControl.d.ts.map +0 -1
  408. package/ol/controls/CopyrightControl.js +0 -68
  409. package/ol/controls/RoutingControl.d.ts +0 -193
  410. package/ol/controls/RoutingControl.d.ts.map +0 -1
  411. package/ol/controls/RoutingControl.js +0 -631
  412. package/ol/controls/StopFinderControl.d.ts +0 -30
  413. package/ol/controls/StopFinderControl.d.ts.map +0 -1
  414. package/ol/controls/index.d.ts +0 -4
  415. package/ol/controls/index.d.ts.map +0 -1
  416. package/ol/index.d.ts +0 -6
  417. package/ol/index.d.ts.map +0 -1
  418. package/ol/layers/Layer.d.ts +0 -86
  419. package/ol/layers/Layer.d.ts.map +0 -1
  420. package/ol/layers/Layer.js +0 -174
  421. package/ol/layers/MapGlLayer.d.ts +0 -67
  422. package/ol/layers/MapGlLayer.d.ts.map +0 -1
  423. package/ol/layers/MapGlLayer.js +0 -218
  424. package/ol/layers/MapboxLayer.d.ts +0 -50
  425. package/ol/layers/MapboxLayer.d.ts.map +0 -1
  426. package/ol/layers/MapboxLayer.js +0 -109
  427. package/ol/layers/MapboxStyleLayer.d.ts +0 -130
  428. package/ol/layers/MapboxStyleLayer.d.ts.map +0 -1
  429. package/ol/layers/MapboxStyleLayer.js +0 -378
  430. package/ol/layers/MaplibreLayer.d.ts.map +0 -1
  431. package/ol/layers/MaplibreLayer.js +0 -34
  432. package/ol/layers/RealtimeLayer.d.ts +0 -202
  433. package/ol/layers/RealtimeLayer.d.ts.map +0 -1
  434. package/ol/layers/RealtimeLayer.js +0 -332
  435. package/ol/layers/RoutingLayer.d.ts +0 -35
  436. package/ol/layers/RoutingLayer.d.ts.map +0 -1
  437. package/ol/layers/RoutingLayer.js +0 -85
  438. package/ol/layers/VectorLayer.d.ts +0 -25
  439. package/ol/layers/VectorLayer.d.ts.map +0 -1
  440. package/ol/layers/VectorLayer.js +0 -38
  441. package/ol/layers/WMSLayer.d.ts +0 -42
  442. package/ol/layers/WMSLayer.d.ts.map +0 -1
  443. package/ol/layers/WMSLayer.js +0 -88
  444. package/ol/layers/index.d.ts +0 -9
  445. package/ol/layers/index.d.ts.map +0 -1
  446. package/ol/styles/fullTrajectoryDelayStyle.d.ts +0 -4
  447. package/ol/styles/fullTrajectoryDelayStyle.d.ts.map +0 -1
  448. package/ol/styles/fullTrajectoryDelayStyle.js +0 -33
  449. package/ol/styles/fullTrajectoryStyle.d.ts +0 -5
  450. package/ol/styles/fullTrajectoryStyle.d.ts.map +0 -1
  451. package/ol/styles/fullTrajectoryStyle.js +0 -44
  452. package/ol/styles/index.d.ts +0 -3
  453. package/ol/styles/index.d.ts.map +0 -1
  454. package/setupTests.d.ts +0 -2
  455. package/setupTests.d.ts.map +0 -1
  456. /package/{api → src/api}/index.js +0 -0
  457. /package/{common → src/common}/index.js +0 -0
  458. /package/{common → src/common}/styles/index.js +0 -0
  459. /package/{mapbox → src/mapbox}/controls/index.js +0 -0
  460. /package/{mapbox → src/mapbox}/index.js +0 -0
  461. /package/{mapbox → src/mapbox}/layers/index.js +0 -0
  462. /package/{mapbox → src/mapbox}/utils/index.js +0 -0
  463. /package/{ol → src/ol}/controls/index.js +0 -0
  464. /package/{ol → src/ol}/index.js +0 -0
  465. /package/{ol → src/ol}/layers/index.js +0 -0
  466. /package/{ol → src/ol}/styles/index.js +0 -0
  467. /package/{types → src/types}/common.d.ts +0 -0
  468. /package/{types → src/types}/index.d.ts +0 -0
  469. /package/{types → src/types}/realtime.d.ts +0 -0
  470. /package/{types → src/types}/routing.d.ts +0 -0
  471. /package/{types → src/types}/stops.d.ts +0 -0
@@ -0,0 +1,2070 @@
1
+ /* eslint-disable */
2
+ /*
3
+
4
+ Software License Agreement (BSD License)
5
+ http://taffydb.com
6
+ Copyright (c)
7
+ All rights reserved.
8
+
9
+
10
+ Redistribution and use of this software in source and binary forms, with or without modification, are permitted provided that the following condition is met:
11
+
12
+ * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
13
+
14
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
15
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
16
+
17
+ */
18
+
19
+ /* jslint browser : true, continue : true,
20
+ devel : true, indent : 2, maxerr : 500,
21
+ newcap : true, nomen : true, plusplus : true,
22
+ regexp : true, sloppy : true, vars : false,
23
+ white : true
24
+ */
25
+
26
+ // BUILD 193d48d, modified by mmikowski to pass jslint
27
+
28
+ // Setup TAFFY name space to return an object with methods
29
+ let TAFFY;
30
+ let exports;
31
+ let T;
32
+ (function () {
33
+ let typeList;
34
+ let makeTest;
35
+ let idx;
36
+ let typeKey;
37
+ let version;
38
+ let TC;
39
+ let idpad;
40
+ let cmax;
41
+ let API;
42
+ let protectJSON;
43
+ let each;
44
+ let eachin;
45
+ let isIndexable;
46
+ let returnFilter;
47
+ let runFilters;
48
+ let numcharsplit;
49
+ let orderByCol;
50
+ let run;
51
+ let intersection;
52
+ let filter;
53
+ let makeCid;
54
+ let safeForJson;
55
+ let isRegexp;
56
+ let sortArgs;
57
+
58
+ if (!TAFFY) {
59
+ // TC = Counter for Taffy DBs on page, used for unique IDs
60
+ // cmax = size of charnumarray conversion cache
61
+ // idpad = zeros to pad record IDs with
62
+ version = '2.7';
63
+ TC = 1;
64
+ idpad = '000000';
65
+ cmax = 1000;
66
+ API = {};
67
+
68
+ sortArgs = function (args) {
69
+ const v = Array.prototype.slice.call(args);
70
+ return v.sort();
71
+ };
72
+
73
+ protectJSON = function (t) {
74
+ // ****************************************
75
+ // *
76
+ // * Takes: a variable
77
+ // * Returns: the variable if object/array or the parsed variable if JSON
78
+ // *
79
+ // ****************************************
80
+ if (TAFFY.isArray(t) || TAFFY.isObject(t)) {
81
+ return t;
82
+ }
83
+ return JSON.parse(t);
84
+ };
85
+
86
+ // gracefully stolen from underscore.js
87
+ intersection = function (array1, array2) {
88
+ return filter(array1, (item) => {
89
+ return array2.indexOf(item) >= 0;
90
+ });
91
+ };
92
+
93
+ // gracefully stolen from underscore.js
94
+ filter = function (obj, iterator, context) {
95
+ const results = [];
96
+ if (obj == null) return results;
97
+ if (Array.prototype.filter && obj.filter === Array.prototype.filter)
98
+ return obj.filter(iterator, context);
99
+ each(obj, (value, index, list) => {
100
+ if (iterator.call(context, value, index, list))
101
+ results[results.length] = value;
102
+ });
103
+ return results;
104
+ };
105
+
106
+ isRegexp = function (aObj) {
107
+ return Object.prototype.toString.call(aObj) === '[object RegExp]';
108
+ };
109
+
110
+ safeForJson = function (aObj) {
111
+ const myResult = T.isArray(aObj) ? [] : T.isObject(aObj) ? {} : null;
112
+ if (aObj === null) return aObj;
113
+ for (const i in aObj) {
114
+ myResult[i] = isRegexp(aObj[i])
115
+ ? aObj[i].toString()
116
+ : T.isArray(aObj[i]) || T.isObject(aObj[i])
117
+ ? safeForJson(aObj[i])
118
+ : aObj[i];
119
+ }
120
+ return myResult;
121
+ };
122
+
123
+ makeCid = function (aContext) {
124
+ const myCid = JSON.stringify(aContext);
125
+ if (myCid.match(/regex/) === null) return myCid;
126
+ return JSON.stringify(safeForJson(aContext));
127
+ };
128
+
129
+ each = function (a, fun, u) {
130
+ let r;
131
+ let i;
132
+ let x;
133
+ let y;
134
+ // ****************************************
135
+ // *
136
+ // * Takes:
137
+ // * a = an object/value or an array of objects/values
138
+ // * f = a function
139
+ // * u = optional flag to describe how to handle undefined values
140
+ // in array of values. True: pass them to the functions,
141
+ // False: skip. Default False;
142
+ // * Purpose: Used to loop over arrays
143
+ // *
144
+ // ****************************************
145
+ if (a && ((T.isArray(a) && a.length === 1) || !T.isArray(a))) {
146
+ fun(T.isArray(a) ? a[0] : a, 0);
147
+ } else {
148
+ for (
149
+ r, i, x = 0, a = T.isArray(a) ? a : [a], y = a.length;
150
+ x < y;
151
+ x++
152
+ ) {
153
+ i = a[x];
154
+ if (!T.isUndefined(i) || u || false) {
155
+ r = fun(i, x);
156
+ if (r === T.EXIT) {
157
+ break;
158
+ }
159
+ }
160
+ }
161
+ }
162
+ };
163
+
164
+ eachin = function (o, fun) {
165
+ // ****************************************
166
+ // *
167
+ // * Takes:
168
+ // * o = an object
169
+ // * f = a function
170
+ // * Purpose: Used to loop over objects
171
+ // *
172
+ // ****************************************
173
+ let x = 0;
174
+ let r;
175
+ let i;
176
+
177
+ for (i in o) {
178
+ if (o.hasOwnProperty(i)) {
179
+ r = fun(o[i], i, x++);
180
+ if (r === T.EXIT) {
181
+ break;
182
+ }
183
+ }
184
+ }
185
+ };
186
+
187
+ API.extend = function (m, f) {
188
+ // ****************************************
189
+ // *
190
+ // * Takes: method name, function
191
+ // * Purpose: Add a custom method to the API
192
+ // *
193
+ // ****************************************
194
+ API[m] = function () {
195
+ return f.apply(this, sortArgs(arguments));
196
+ };
197
+ };
198
+
199
+ isIndexable = function (f) {
200
+ let i;
201
+ // Check to see if record ID
202
+ if (T.isString(f) && /[t][0-9]*[r][0-9]*/i.test(f)) {
203
+ return true;
204
+ }
205
+ // Check to see if record
206
+ if (T.isObject(f) && f.___id && f.___s) {
207
+ return true;
208
+ }
209
+
210
+ // Check to see if array of indexes
211
+ if (T.isArray(f)) {
212
+ i = true;
213
+ each(f, (r) => {
214
+ if (!isIndexable(r)) {
215
+ i = false;
216
+
217
+ return TAFFY.EXIT;
218
+ }
219
+ });
220
+ return i;
221
+ }
222
+
223
+ return false;
224
+ };
225
+
226
+ runFilters = function (r, filter) {
227
+ // ****************************************
228
+ // *
229
+ // * Takes: takes a record and a collection of filters
230
+ // * Returns: true if the record matches, false otherwise
231
+ // ****************************************
232
+ let match = true;
233
+
234
+ each(filter, (mf) => {
235
+ switch (T.typeOf(mf)) {
236
+ case 'function':
237
+ // run function
238
+ if (!mf.apply(r)) {
239
+ match = false;
240
+ return TAFFY.EXIT;
241
+ }
242
+ break;
243
+ case 'array':
244
+ // loop array and treat like a SQL or
245
+ match =
246
+ mf.length === 1
247
+ ? runFilters(r, mf[0])
248
+ : mf.length === 2
249
+ ? runFilters(r, mf[0]) || runFilters(r, mf[1])
250
+ : mf.length === 3
251
+ ? runFilters(r, mf[0]) ||
252
+ runFilters(r, mf[1]) ||
253
+ runFilters(r, mf[2])
254
+ : mf.length === 4
255
+ ? runFilters(r, mf[0]) ||
256
+ runFilters(r, mf[1]) ||
257
+ runFilters(r, mf[2]) ||
258
+ runFilters(r, mf[3])
259
+ : false;
260
+ if (mf.length > 4) {
261
+ each(mf, (f) => {
262
+ if (runFilters(r, f)) {
263
+ match = true;
264
+ }
265
+ });
266
+ }
267
+ break;
268
+ }
269
+ });
270
+
271
+ return match;
272
+ };
273
+
274
+ returnFilter = function (f) {
275
+ // ****************************************
276
+ // *
277
+ // * Takes: filter object
278
+ // * Returns: a filter function
279
+ // * Purpose: Take a filter object and return a function that can be used to compare
280
+ // * a TaffyDB record to see if the record matches a query
281
+ // ****************************************
282
+ const nf = [];
283
+ if (T.isString(f) && /[t][0-9]*[r][0-9]*/i.test(f)) {
284
+ f = { ___id: f };
285
+ }
286
+ if (T.isArray(f)) {
287
+ // if we are working with an array
288
+
289
+ each(f, (r) => {
290
+ // loop the array and return a filter func for each value
291
+ nf.push(returnFilter(r));
292
+ });
293
+ // now build a func to loop over the filters and return true if ANY of the filters match
294
+ // This handles logical OR expressions
295
+ f = function () {
296
+ const that = this;
297
+ let match = false;
298
+ each(nf, (f) => {
299
+ if (runFilters(that, f)) {
300
+ match = true;
301
+ }
302
+ });
303
+ return match;
304
+ };
305
+ return f;
306
+ }
307
+ // if we are dealing with an Object
308
+ if (T.isObject(f)) {
309
+ if (T.isObject(f) && f.___id && f.___s) {
310
+ f = { ___id: f.___id };
311
+ }
312
+
313
+ // Loop over each value on the object to prep match type and match value
314
+ eachin(f, (v, i) => {
315
+ // default match type to IS/Equals
316
+ if (!T.isObject(v)) {
317
+ v = {
318
+ is: v,
319
+ };
320
+ }
321
+ // loop over each value on the value object - if any
322
+ eachin(v, (mtest, s) => {
323
+ // s = match type, e.g. is, hasAll, like, etc
324
+ const c = [];
325
+ let looper;
326
+
327
+ // function to loop and apply filter
328
+ looper =
329
+ s === 'hasAll'
330
+ ? function (mtest, func) {
331
+ func(mtest);
332
+ }
333
+ : each;
334
+
335
+ // loop over each test
336
+ looper(mtest, (mtest) => {
337
+ // su = match success
338
+ // f = match false
339
+ let su = true;
340
+ const f = false;
341
+ let matchFunc;
342
+
343
+ // push a function onto the filter collection to do the matching
344
+ matchFunc = function () {
345
+ // get the value from the record
346
+ const mvalue = this[i];
347
+ const eqeq = '==';
348
+ const bangeq = '!=';
349
+ const eqeqeq = '===';
350
+ const lt = '<';
351
+ const gt = '>';
352
+ const lteq = '<=';
353
+ const gteq = '>=';
354
+ const bangeqeq = '!==';
355
+ let r;
356
+
357
+ if (typeof mvalue === 'undefined') {
358
+ return false;
359
+ }
360
+
361
+ if (s.indexOf('!') === 0 && s !== bangeq && s !== bangeqeq) {
362
+ // if the filter name starts with ! as in '!is' then reverse the match logic and remove the !
363
+ su = false;
364
+ s = s.substring(1, s.length);
365
+ }
366
+ // get the match results based on the s/match type
367
+ /* jslint eqeq : true */
368
+ r =
369
+ s === 'regex'
370
+ ? mtest.test(mvalue)
371
+ : s === 'lt' || s === lt
372
+ ? mvalue < mtest
373
+ : s === 'gt' || s === gt
374
+ ? mvalue > mtest
375
+ : s === 'lte' || s === lteq
376
+ ? mvalue <= mtest
377
+ : s === 'gte' || s === gteq
378
+ ? mvalue >= mtest
379
+ : s === 'left'
380
+ ? mvalue.indexOf(mtest) === 0
381
+ : s === 'leftnocase'
382
+ ? mvalue.toLowerCase().indexOf(mtest.toLowerCase()) === 0
383
+ : s === 'right'
384
+ ? mvalue.substring(mvalue.length - mtest.length) === mtest
385
+ : s === 'rightnocase'
386
+ ? mvalue
387
+ .toLowerCase()
388
+ .substring(mvalue.length - mtest.length) ===
389
+ mtest.toLowerCase()
390
+ : s === 'like'
391
+ ? mvalue.indexOf(mtest) >= 0
392
+ : s === 'likenocase'
393
+ ? mvalue.toLowerCase().indexOf(mtest.toLowerCase()) >= 0
394
+ : s === eqeqeq || s === 'is'
395
+ ? mvalue === mtest
396
+ : s === eqeq
397
+ ? mvalue == mtest
398
+ : s === bangeqeq
399
+ ? mvalue !== mtest
400
+ : s === bangeq
401
+ ? mvalue != mtest
402
+ : s === 'isnocase'
403
+ ? mvalue.toLowerCase
404
+ ? mvalue.toLowerCase() === mtest.toLowerCase()
405
+ : mvalue === mtest
406
+ : s === 'has'
407
+ ? T.has(mvalue, mtest)
408
+ : s === 'hasall'
409
+ ? T.hasAll(mvalue, mtest)
410
+ : s === 'contains'
411
+ ? TAFFY.isArray(mvalue) && mvalue.indexOf(mtest) > -1
412
+ : s.indexOf('is') === -1 &&
413
+ !TAFFY.isNull(mvalue) &&
414
+ !TAFFY.isUndefined(mvalue) &&
415
+ !TAFFY.isObject(mtest) &&
416
+ !TAFFY.isArray(mtest)
417
+ ? mtest === mvalue[s]
418
+ : T[s] && T.isFunction(T[s]) && s.indexOf('is') === 0
419
+ ? T[s](mvalue) === mtest
420
+ : T[s] && T.isFunction(T[s])
421
+ ? T[s](mvalue, mtest)
422
+ : false;
423
+ /* jslint eqeq : false */
424
+ r = r && !su ? false : !r && !su ? true : r;
425
+
426
+ return r;
427
+ };
428
+ c.push(matchFunc);
429
+ });
430
+ // if only one filter in the collection push it onto the filter list without the array
431
+ if (c.length === 1) {
432
+ nf.push(c[0]);
433
+ } else {
434
+ // else build a function to loop over all the filters and return true only if ALL match
435
+ // this is a logical AND
436
+ nf.push(function () {
437
+ const that = this;
438
+ let match = false;
439
+ each(c, (f) => {
440
+ if (f.apply(that)) {
441
+ match = true;
442
+ }
443
+ });
444
+ return match;
445
+ });
446
+ }
447
+ });
448
+ });
449
+ // finally return a single function that wraps all the other functions and will run a query
450
+ // where all functions have to return true for a record to appear in a query result
451
+ f = function () {
452
+ const that = this;
453
+ let match = true;
454
+ // faster if less than 4 functions
455
+ match =
456
+ nf.length === 1 && !nf[0].apply(that)
457
+ ? false
458
+ : nf.length === 2 && (!nf[0].apply(that) || !nf[1].apply(that))
459
+ ? false
460
+ : nf.length === 3 &&
461
+ (!nf[0].apply(that) || !nf[1].apply(that) || !nf[2].apply(that))
462
+ ? false
463
+ : !(
464
+ nf.length === 4 &&
465
+ (!nf[0].apply(that) ||
466
+ !nf[1].apply(that) ||
467
+ !nf[2].apply(that) ||
468
+ !nf[3].apply(that))
469
+ );
470
+ if (nf.length > 4) {
471
+ each(nf, (f) => {
472
+ if (!runFilters(that, f)) {
473
+ match = false;
474
+ }
475
+ });
476
+ }
477
+ return match;
478
+ };
479
+ return f;
480
+ }
481
+
482
+ // if function
483
+ if (T.isFunction(f)) {
484
+ return f;
485
+ }
486
+ };
487
+
488
+ orderByCol = function (ar, o) {
489
+ // ****************************************
490
+ // *
491
+ // * Takes: takes an array and a sort object
492
+ // * Returns: the array sorted
493
+ // * Purpose: Accept filters such as "[col], [col2]" or "[col] desc" and sort on those columns
494
+ // *
495
+ // ****************************************
496
+
497
+ const sortFunc = function (a, b) {
498
+ // function to pass to the native array.sort to sort an array
499
+ let r = 0;
500
+
501
+ T.each(o, (sd) => {
502
+ // loop over the sort instructions
503
+ // get the column name
504
+ let o;
505
+ let col;
506
+ let dir;
507
+ let c;
508
+ let d;
509
+ o = sd.split(' ');
510
+ col = o[0];
511
+
512
+ // get the direction
513
+ dir = o.length === 1 ? 'logical' : o[1];
514
+
515
+ if (dir === 'logical') {
516
+ // if dir is logical than grab the charnum arrays for the two values we are looking at
517
+ c = numcharsplit(a[col]);
518
+ d = numcharsplit(b[col]);
519
+ // loop over the charnumarrays until one value is higher than the other
520
+ T.each(c.length <= d.length ? c : d, (x, i) => {
521
+ if (c[i] < d[i]) {
522
+ r = -1;
523
+ return TAFFY.EXIT;
524
+ }
525
+ if (c[i] > d[i]) {
526
+ r = 1;
527
+ return TAFFY.EXIT;
528
+ }
529
+ });
530
+ } else if (dir === 'logicaldesc') {
531
+ // if logicaldesc than grab the charnum arrays for the two values we are looking at
532
+ c = numcharsplit(a[col]);
533
+ d = numcharsplit(b[col]);
534
+ // loop over the charnumarrays until one value is lower than the other
535
+ T.each(c.length <= d.length ? c : d, (x, i) => {
536
+ if (c[i] > d[i]) {
537
+ r = -1;
538
+ return TAFFY.EXIT;
539
+ }
540
+ if (c[i] < d[i]) {
541
+ r = 1;
542
+ return TAFFY.EXIT;
543
+ }
544
+ });
545
+ } else if (dir === 'asec' && a[col] < b[col]) {
546
+ // if asec - default - check to see which is higher
547
+ r = -1;
548
+ return T.EXIT;
549
+ } else if (dir === 'asec' && a[col] > b[col]) {
550
+ // if asec - default - check to see which is higher
551
+ r = 1;
552
+ return T.EXIT;
553
+ } else if (dir === 'desc' && a[col] > b[col]) {
554
+ // if desc check to see which is lower
555
+ r = -1;
556
+ return T.EXIT;
557
+ } else if (dir === 'desc' && a[col] < b[col]) {
558
+ // if desc check to see which is lower
559
+ r = 1;
560
+ return T.EXIT;
561
+ }
562
+ // if r is still 0 and we are doing a logical sort than look to see if one array is longer than the other
563
+ if (r === 0 && dir === 'logical' && c.length < d.length) {
564
+ r = -1;
565
+ } else if (r === 0 && dir === 'logical' && c.length > d.length) {
566
+ r = 1;
567
+ } else if (r === 0 && dir === 'logicaldesc' && c.length > d.length) {
568
+ r = -1;
569
+ } else if (r === 0 && dir === 'logicaldesc' && c.length < d.length) {
570
+ r = 1;
571
+ }
572
+
573
+ if (r !== 0) {
574
+ return T.EXIT;
575
+ }
576
+ });
577
+ return r;
578
+ };
579
+ // call the sort function and return the newly sorted array
580
+ return ar && ar.push ? ar.sort(sortFunc) : ar;
581
+ };
582
+
583
+ // ****************************************
584
+ // *
585
+ // * Takes: a string containing numbers and letters and turn it into an array
586
+ // * Returns: return an array of numbers and letters
587
+ // * Purpose: Used for logical sorting. String Example: 12ABC results: [12,'ABC']
588
+ // ****************************************
589
+ (function () {
590
+ // creates a cache for numchar conversions
591
+ let cache = {};
592
+ let cachcounter = 0;
593
+ // creates the numcharsplit function
594
+ numcharsplit = function (thing) {
595
+ // if over 1000 items exist in the cache, clear it and start over
596
+ if (cachcounter > cmax) {
597
+ cache = {};
598
+ cachcounter = 0;
599
+ }
600
+
601
+ // if a cache can be found for a numchar then return its array value
602
+ return (
603
+ cache[`_${thing}`] ||
604
+ (function () {
605
+ // otherwise do the conversion
606
+ // make sure it is a string and setup so other variables
607
+ const nthing = String(thing);
608
+ const na = [];
609
+ let rv = '_';
610
+ let rt = '';
611
+ let x;
612
+ let xx;
613
+ let c;
614
+
615
+ // loop over the string char by char
616
+ for (x = 0, xx = nthing.length; x < xx; x++) {
617
+ // take the char at each location
618
+ c = nthing.charCodeAt(x);
619
+ // check to see if it is a valid number char and append it to the array.
620
+ // if last char was a string push the string to the charnum array
621
+ if ((c >= 48 && c <= 57) || c === 46) {
622
+ if (rt !== 'n') {
623
+ rt = 'n';
624
+ na.push(rv.toLowerCase());
625
+ rv = '';
626
+ }
627
+ rv += nthing.charAt(x);
628
+ } else {
629
+ // check to see if it is a valid string char and append to string
630
+ // if last char was a number push the whole number to the charnum array
631
+ if (rt !== 's') {
632
+ rt = 's';
633
+ na.push(parseFloat(rv));
634
+ rv = '';
635
+ }
636
+ rv += nthing.charAt(x);
637
+ }
638
+ }
639
+ // once done, push the last value to the charnum array and remove the first uneeded item
640
+ na.push(rt === 'n' ? parseFloat(rv) : rv.toLowerCase());
641
+ na.shift();
642
+ // add to cache
643
+ cache[`_${thing}`] = na;
644
+ cachcounter++;
645
+ // return charnum array
646
+ return na;
647
+ })()
648
+ );
649
+ };
650
+ })();
651
+
652
+ // ****************************************
653
+ // *
654
+ // * Runs a query
655
+ // ****************************************
656
+
657
+ run = function () {
658
+ this.context({
659
+ results: this.getDBI().query(this.context()),
660
+ });
661
+ };
662
+
663
+ API.extend('filter', function () {
664
+ // ****************************************
665
+ // *
666
+ // * Takes: takes unlimited filter objects as arguments
667
+ // * Returns: method collection
668
+ // * Purpose: Take filters as objects and cache functions for later lookup when a query is run
669
+ // ****************************************
670
+ const nc = TAFFY.mergeObj(this.context(), { run: null });
671
+ const nq = [];
672
+ each(nc.q, (v) => {
673
+ nq.push(v);
674
+ });
675
+ nc.q = nq;
676
+ // Hadnle passing of ___ID or a record on lookup.
677
+ each(sortArgs(arguments), (f) => {
678
+ nc.q.push(returnFilter(f));
679
+ nc.filterRaw.push(f);
680
+ });
681
+
682
+ return this.getroot(nc);
683
+ });
684
+
685
+ API.extend('order', function (o) {
686
+ // ****************************************
687
+ // *
688
+ // * Purpose: takes a string and creates an array of order instructions to be used with a query
689
+ // ****************************************
690
+
691
+ o = o.split(',');
692
+ const x = [];
693
+ let nc;
694
+
695
+ each(o, (r) => {
696
+ x.push(r.replace(/^\s*/, '').replace(/\s*$/, ''));
697
+ });
698
+
699
+ nc = TAFFY.mergeObj(this.context(), { sort: null });
700
+ nc.order = x;
701
+
702
+ return this.getroot(nc);
703
+ });
704
+
705
+ API.extend('limit', function (n) {
706
+ // ****************************************
707
+ // *
708
+ // * Purpose: takes a limit number to limit the number of rows returned by a query. Will update the results
709
+ // * of a query
710
+ // ****************************************
711
+ const nc = TAFFY.mergeObj(this.context(), {});
712
+ let limitedresults;
713
+
714
+ nc.limit = n;
715
+
716
+ if (nc.run && nc.sort) {
717
+ limitedresults = [];
718
+ each(nc.results, (i, x) => {
719
+ if (x + 1 > n) {
720
+ return TAFFY.EXIT;
721
+ }
722
+ limitedresults.push(i);
723
+ });
724
+ nc.results = limitedresults;
725
+ }
726
+
727
+ return this.getroot(nc);
728
+ });
729
+
730
+ API.extend('start', function (n) {
731
+ // ****************************************
732
+ // *
733
+ // * Purpose: takes a limit number to limit the number of rows returned by a query. Will update the results
734
+ // * of a query
735
+ // ****************************************
736
+ let nc = TAFFY.mergeObj(this.context(), {});
737
+ let limitedresults;
738
+
739
+ nc.start = n;
740
+
741
+ if (nc.run && nc.sort && !nc.limit) {
742
+ limitedresults = [];
743
+ each(nc.results, (i, x) => {
744
+ if (x + 1 > n) {
745
+ limitedresults.push(i);
746
+ }
747
+ });
748
+ nc.results = limitedresults;
749
+ } else {
750
+ nc = TAFFY.mergeObj(this.context(), { run: null, start: n });
751
+ }
752
+
753
+ return this.getroot(nc);
754
+ });
755
+
756
+ API.extend('update', function (arg0, arg1, arg2) {
757
+ // ****************************************
758
+ // *
759
+ // * Takes: a object and passes it off DBI update method for all matched records
760
+ // ****************************************
761
+ let runEvent = true;
762
+ let o = {};
763
+ const args = sortArgs(arguments);
764
+ let that;
765
+ if (
766
+ TAFFY.isString(arg0) &&
767
+ (arguments.length === 2 || arguments.length === 3)
768
+ ) {
769
+ o[arg0] = arg1;
770
+ if (arguments.length === 3) {
771
+ runEvent = arg2;
772
+ }
773
+ } else {
774
+ o = arg0;
775
+ if (args.length === 2) {
776
+ runEvent = arg1;
777
+ }
778
+ }
779
+
780
+ that = this;
781
+ run.call(this);
782
+ each(this.context().results, (r) => {
783
+ let c = o;
784
+ if (TAFFY.isFunction(c)) {
785
+ c = c.apply(TAFFY.mergeObj(r, {}));
786
+ } else if (T.isFunction(c)) {
787
+ c = c(TAFFY.mergeObj(r, {}));
788
+ }
789
+ if (TAFFY.isObject(c)) {
790
+ that.getDBI().update(r.___id, c, runEvent);
791
+ }
792
+ });
793
+ if (this.context().results.length) {
794
+ this.context({ run: null });
795
+ }
796
+ return this;
797
+ });
798
+ API.extend('remove', function (runEvent) {
799
+ // ****************************************
800
+ // *
801
+ // * Purpose: removes records from the DB via the remove and removeCommit DBI methods
802
+ // ****************************************
803
+ const that = this;
804
+ let c = 0;
805
+ run.call(this);
806
+ each(this.context().results, (r) => {
807
+ that.getDBI().remove(r.___id);
808
+ c++;
809
+ });
810
+ if (this.context().results.length) {
811
+ this.context({
812
+ run: null,
813
+ });
814
+ that.getDBI().removeCommit(runEvent);
815
+ }
816
+
817
+ return c;
818
+ });
819
+
820
+ API.extend('count', function () {
821
+ // ****************************************
822
+ // *
823
+ // * Returns: The length of a query result
824
+ // ****************************************
825
+ run.call(this);
826
+ return this.context().results.length;
827
+ });
828
+
829
+ API.extend('callback', function (f, delay) {
830
+ // ****************************************
831
+ // *
832
+ // * Returns null;
833
+ // * Runs a function on return of run.call
834
+ // ****************************************
835
+ if (f) {
836
+ const that = this;
837
+ setTimeout(() => {
838
+ run.call(that);
839
+ f.call(that.getroot(that.context()));
840
+ }, delay || 0);
841
+ }
842
+
843
+ return null;
844
+ });
845
+
846
+ API.extend('get', function () {
847
+ // ****************************************
848
+ // *
849
+ // * Returns: An array of all matching records
850
+ // ****************************************
851
+ run.call(this);
852
+ return this.context().results;
853
+ });
854
+
855
+ API.extend('stringify', function () {
856
+ // ****************************************
857
+ // *
858
+ // * Returns: An JSON string of all matching records
859
+ // ****************************************
860
+ return JSON.stringify(this.get());
861
+ });
862
+ API.extend('first', function () {
863
+ // ****************************************
864
+ // *
865
+ // * Returns: The first matching record
866
+ // ****************************************
867
+ run.call(this);
868
+ return this.context().results[0] || false;
869
+ });
870
+ API.extend('last', function () {
871
+ // ****************************************
872
+ // *
873
+ // * Returns: The last matching record
874
+ // ****************************************
875
+ run.call(this);
876
+ return this.context().results[this.context().results.length - 1] || false;
877
+ });
878
+
879
+ API.extend('sum', function () {
880
+ // ****************************************
881
+ // *
882
+ // * Takes: column to sum up
883
+ // * Returns: Sums the values of a column
884
+ // ****************************************
885
+ let total = 0;
886
+ const that = this;
887
+ run.call(that);
888
+ each(sortArgs(arguments), (c) => {
889
+ each(that.context().results, (r) => {
890
+ total += r[c] || 0;
891
+ });
892
+ });
893
+ return total;
894
+ });
895
+
896
+ API.extend('min', function (c) {
897
+ // ****************************************
898
+ // *
899
+ // * Takes: column to find min
900
+ // * Returns: the lowest value
901
+ // ****************************************
902
+ let lowest = null;
903
+ run.call(this);
904
+ each(this.context().results, (r) => {
905
+ if (lowest === null || r[c] < lowest) {
906
+ lowest = r[c];
907
+ }
908
+ });
909
+ return lowest;
910
+ });
911
+
912
+ // Taffy innerJoin Extension (OCD edition)
913
+ // =======================================
914
+ //
915
+ // How to Use
916
+ // **********
917
+ //
918
+ // left_table.innerJoin( right_table, condition1 <,... conditionN> )
919
+ //
920
+ // A condition can take one of 2 forms:
921
+ //
922
+ // 1. An ARRAY with 2 or 3 values:
923
+ // A column name from the left table, an optional comparison string,
924
+ // and column name from the right table. The condition passes if the test
925
+ // indicated is true. If the condition string is omitted, '===' is assumed.
926
+ // EXAMPLES: [ 'last_used_time', '>=', 'current_use_time' ], [ 'user_id','id' ]
927
+ //
928
+ // 2. A FUNCTION:
929
+ // The function receives a left table row and right table row during the
930
+ // cartesian join. If the function returns true for the rows considered,
931
+ // the merged row is included in the result set.
932
+ // EXAMPLE: function (l,r){ return l.name === r.label; }
933
+ //
934
+ // Conditions are considered in the order they are presented. Therefore the best
935
+ // performance is realized when the least expensive and highest prune-rate
936
+ // conditions are placed first, since if they return false Taffy skips any
937
+ // further condition tests.
938
+ //
939
+ // Other notes
940
+ // ***********
941
+ //
942
+ // This code passes jslint with the exception of 2 warnings about
943
+ // the '==' and '!=' lines. We can't do anything about that short of
944
+ // deleting the lines.
945
+ //
946
+ // Credits
947
+ // *******
948
+ //
949
+ // Heavily based upon the work of Ian Toltz.
950
+ // Revisions to API by Michael Mikowski.
951
+ // Code convention per standards in http://manning.com/mikowski
952
+ (function () {
953
+ const innerJoinFunction = (function () {
954
+ let fnCompareList;
955
+ let fnCombineRow;
956
+ let fnMain;
957
+
958
+ fnCompareList = function (left_row, right_row, arg_list) {
959
+ let data_lt;
960
+ let data_rt;
961
+ let op_code;
962
+ let error;
963
+
964
+ if (arg_list.length === 2) {
965
+ data_lt = left_row[arg_list[0]];
966
+ op_code = '===';
967
+ data_rt = right_row[arg_list[1]];
968
+ } else {
969
+ data_lt = left_row[arg_list[0]];
970
+ op_code = arg_list[1];
971
+ data_rt = right_row[arg_list[2]];
972
+ }
973
+
974
+ /* jslint eqeq : true */
975
+ switch (op_code) {
976
+ case '===':
977
+ return data_lt === data_rt;
978
+ case '!==':
979
+ return data_lt !== data_rt;
980
+ case '<':
981
+ return data_lt < data_rt;
982
+ case '>':
983
+ return data_lt > data_rt;
984
+ case '<=':
985
+ return data_lt <= data_rt;
986
+ case '>=':
987
+ return data_lt >= data_rt;
988
+ case '==':
989
+ return data_lt == data_rt;
990
+ case '!=':
991
+ return data_lt != data_rt;
992
+ default:
993
+ throw `${String(op_code)} is not supported`;
994
+ }
995
+ // 'jslint eqeq : false' here results in
996
+ // "Unreachable '/*jslint' after 'return'".
997
+ // We don't need it though, as the rule exception
998
+ // is discarded at the end of this functional scope
999
+ };
1000
+
1001
+ fnCombineRow = function (left_row, right_row) {
1002
+ const out_map = {};
1003
+ let i;
1004
+ let prefix;
1005
+
1006
+ for (i in left_row) {
1007
+ if (left_row.hasOwnProperty(i)) {
1008
+ out_map[i] = left_row[i];
1009
+ }
1010
+ }
1011
+ for (i in right_row) {
1012
+ if (right_row.hasOwnProperty(i) && i !== '___id' && i !== '___s') {
1013
+ prefix = !TAFFY.isUndefined(out_map[i]) ? 'right_' : '';
1014
+ out_map[prefix + String(i)] = right_row[i];
1015
+ }
1016
+ }
1017
+ return out_map;
1018
+ };
1019
+
1020
+ fnMain = function (table) {
1021
+ let right_table;
1022
+ let i;
1023
+ const arg_list = sortArgs(arguments);
1024
+ const arg_length = arg_list.length;
1025
+ const result_list = [];
1026
+ if (typeof table.filter !== 'function') {
1027
+ if (table.TAFFY) {
1028
+ right_table = table();
1029
+ } else {
1030
+ throw 'TAFFY DB or result not supplied';
1031
+ }
1032
+ } else {
1033
+ right_table = table;
1034
+ }
1035
+
1036
+ this.context({
1037
+ results: this.getDBI().query(this.context()),
1038
+ });
1039
+
1040
+ TAFFY.each(this.context().results, (left_row) => {
1041
+ right_table.each((right_row) => {
1042
+ let arg_data;
1043
+ let is_ok = true;
1044
+ for (i = 1; i < arg_length; i++) {
1045
+ arg_data = arg_list[i];
1046
+ if (typeof arg_data === 'function') {
1047
+ is_ok = arg_data(left_row, right_row);
1048
+ } else if (typeof arg_data === 'object' && arg_data.length) {
1049
+ is_ok = fnCompareList(left_row, right_row, arg_data);
1050
+ } else {
1051
+ is_ok = false;
1052
+ }
1053
+
1054
+ if (!is_ok) {
1055
+ break;
1056
+ } // short circuit
1057
+ }
1058
+
1059
+ if (is_ok) {
1060
+ result_list.push(fnCombineRow(left_row, right_row));
1061
+ }
1062
+ });
1063
+ });
1064
+ return TAFFY(result_list)();
1065
+ };
1066
+
1067
+ return fnMain;
1068
+ })();
1069
+
1070
+ API.extend('join', innerJoinFunction);
1071
+ })();
1072
+
1073
+ API.extend('max', function (c) {
1074
+ // ****************************************
1075
+ // *
1076
+ // * Takes: column to find max
1077
+ // * Returns: the highest value
1078
+ // ****************************************
1079
+ let highest = null;
1080
+ run.call(this);
1081
+ each(this.context().results, (r) => {
1082
+ if (highest === null || r[c] > highest) {
1083
+ highest = r[c];
1084
+ }
1085
+ });
1086
+ return highest;
1087
+ });
1088
+
1089
+ API.extend('select', function () {
1090
+ // ****************************************
1091
+ // *
1092
+ // * Takes: columns to select values into an array
1093
+ // * Returns: array of values
1094
+ // * Note if more than one column is given an array of arrays is returned
1095
+ // ****************************************
1096
+
1097
+ const ra = [];
1098
+ const args = sortArgs(arguments);
1099
+ run.call(this);
1100
+ if (arguments.length === 1) {
1101
+ each(this.context().results, (r) => {
1102
+ ra.push(r[args[0]]);
1103
+ });
1104
+ } else {
1105
+ each(this.context().results, (r) => {
1106
+ const row = [];
1107
+ each(args, (c) => {
1108
+ row.push(r[c]);
1109
+ });
1110
+ ra.push(row);
1111
+ });
1112
+ }
1113
+ return ra;
1114
+ });
1115
+ API.extend('distinct', function () {
1116
+ // ****************************************
1117
+ // *
1118
+ // * Takes: columns to select unique alues into an array
1119
+ // * Returns: array of values
1120
+ // * Note if more than one column is given an array of arrays is returned
1121
+ // ****************************************
1122
+ const ra = [];
1123
+ const args = sortArgs(arguments);
1124
+ run.call(this);
1125
+ if (arguments.length === 1) {
1126
+ each(this.context().results, (r) => {
1127
+ const v = r[args[0]];
1128
+ let dup = false;
1129
+ each(ra, (d) => {
1130
+ if (v === d) {
1131
+ dup = true;
1132
+ return TAFFY.EXIT;
1133
+ }
1134
+ });
1135
+ if (!dup) {
1136
+ ra.push(v);
1137
+ }
1138
+ });
1139
+ } else {
1140
+ each(this.context().results, (r) => {
1141
+ const row = [];
1142
+ let dup = false;
1143
+ each(args, (c) => {
1144
+ row.push(r[c]);
1145
+ });
1146
+ each(ra, (d) => {
1147
+ let ldup = true;
1148
+ each(args, (c, i) => {
1149
+ if (row[i] !== d[i]) {
1150
+ ldup = false;
1151
+ return TAFFY.EXIT;
1152
+ }
1153
+ });
1154
+ if (ldup) {
1155
+ dup = true;
1156
+ return TAFFY.EXIT;
1157
+ }
1158
+ });
1159
+ if (!dup) {
1160
+ ra.push(row);
1161
+ }
1162
+ });
1163
+ }
1164
+ return ra;
1165
+ });
1166
+ API.extend('supplant', function (template, returnarray) {
1167
+ // ****************************************
1168
+ // *
1169
+ // * Takes: a string template formated with key to be replaced with values from the rows, flag to determine if we want array of strings
1170
+ // * Returns: array of values or a string
1171
+ // ****************************************
1172
+ const ra = [];
1173
+ run.call(this);
1174
+ each(this.context().results, (r) => {
1175
+ // TODO: The curly braces used to be unescaped
1176
+ ra.push(
1177
+ template.replace(/\{([^\{\}]*)\}/g, (a, b) => {
1178
+ const v = r[b];
1179
+ return typeof v === 'string' || typeof v === 'number' ? v : a;
1180
+ }),
1181
+ );
1182
+ });
1183
+ return !returnarray ? ra.join('') : ra;
1184
+ });
1185
+
1186
+ API.extend('each', function (m) {
1187
+ // ****************************************
1188
+ // *
1189
+ // * Takes: a function
1190
+ // * Purpose: loops over every matching record and applies the function
1191
+ // ****************************************
1192
+ run.call(this);
1193
+ each(this.context().results, m);
1194
+ return this;
1195
+ });
1196
+ API.extend('map', function (m) {
1197
+ // ****************************************
1198
+ // *
1199
+ // * Takes: a function
1200
+ // * Purpose: loops over every matching record and applies the function, returing the results in an array
1201
+ // ****************************************
1202
+ const ra = [];
1203
+ run.call(this);
1204
+ each(this.context().results, (r) => {
1205
+ ra.push(m(r));
1206
+ });
1207
+ return ra;
1208
+ });
1209
+
1210
+ T = function (d) {
1211
+ // ****************************************
1212
+ // *
1213
+ // * T is the main TAFFY object
1214
+ // * Takes: an array of objects or JSON
1215
+ // * Returns a new TAFFYDB
1216
+ // ****************************************
1217
+ let TOb = [];
1218
+ let ID = {};
1219
+ let RC = 1;
1220
+ let settings = {
1221
+ template: false,
1222
+ onInsert: false,
1223
+ onUpdate: false,
1224
+ onRemove: false,
1225
+ onDBChange: false,
1226
+ storageName: false,
1227
+ forcePropertyCase: null,
1228
+ cacheSize: 100,
1229
+ name: '',
1230
+ };
1231
+ let dm = new Date();
1232
+ let CacheCount = 0;
1233
+ let CacheClear = 0;
1234
+ let Cache = {};
1235
+ let DBI;
1236
+ let runIndexes;
1237
+ let root;
1238
+ // ****************************************
1239
+ // *
1240
+ // * TOb = this database
1241
+ // * ID = collection of the record IDs and locations within the DB, used for fast lookups
1242
+ // * RC = record counter, used for creating IDs
1243
+ // * settings.template = the template to merge all new records with
1244
+ // * settings.onInsert = event given a copy of the newly inserted record
1245
+ // * settings.onUpdate = event given the original record, the changes, and the new record
1246
+ // * settings.onRemove = event given the removed record
1247
+ // * settings.forcePropertyCase = on insert force the proprty case to be lower or upper. default lower, null/undefined will leave case as is
1248
+ // * dm = the modify date of the database, used for query caching
1249
+ // ****************************************
1250
+
1251
+ runIndexes = function (indexes) {
1252
+ // ****************************************
1253
+ // *
1254
+ // * Takes: a collection of indexes
1255
+ // * Returns: collection with records matching indexed filters
1256
+ // ****************************************
1257
+
1258
+ let records = [];
1259
+ let UniqueEnforce = false;
1260
+
1261
+ if (indexes.length === 0) {
1262
+ return TOb;
1263
+ }
1264
+
1265
+ each(indexes, (f) => {
1266
+ // Check to see if record ID
1267
+ if (T.isString(f) && /[t][0-9]*[r][0-9]*/i.test(f) && TOb[ID[f]]) {
1268
+ records.push(TOb[ID[f]]);
1269
+ UniqueEnforce = true;
1270
+ }
1271
+ // Check to see if record
1272
+ if (T.isObject(f) && f.___id && f.___s && TOb[ID[f.___id]]) {
1273
+ records.push(TOb[ID[f.___id]]);
1274
+ UniqueEnforce = true;
1275
+ }
1276
+ // Check to see if array of indexes
1277
+ if (T.isArray(f)) {
1278
+ each(f, (r) => {
1279
+ each(runIndexes(r), (rr) => {
1280
+ records.push(rr);
1281
+ });
1282
+ });
1283
+ }
1284
+ });
1285
+ if (UniqueEnforce && records.length > 1) {
1286
+ records = [];
1287
+ }
1288
+
1289
+ return records;
1290
+ };
1291
+
1292
+ DBI = {
1293
+ // ****************************************
1294
+ // *
1295
+ // * The DBI is the internal DataBase Interface that interacts with the data
1296
+ // ****************************************
1297
+ dm(nd) {
1298
+ // ****************************************
1299
+ // *
1300
+ // * Takes: an optional new modify date
1301
+ // * Purpose: used to get and set the DB modify date
1302
+ // ****************************************
1303
+ if (nd) {
1304
+ dm = nd;
1305
+ Cache = {};
1306
+ CacheCount = 0;
1307
+ CacheClear = 0;
1308
+ }
1309
+ if (settings.onDBChange) {
1310
+ setTimeout(() => {
1311
+ settings.onDBChange.call(TOb);
1312
+ }, 0);
1313
+ }
1314
+ if (settings.storageName) {
1315
+ setTimeout(() => {
1316
+ localStorage.setItem(
1317
+ `taffy_${settings.storageName}`,
1318
+ JSON.stringify(TOb),
1319
+ );
1320
+ });
1321
+ }
1322
+ return dm;
1323
+ },
1324
+ insert(i, runEvent) {
1325
+ // ****************************************
1326
+ // *
1327
+ // * Takes: a new record to insert
1328
+ // * Purpose: merge the object with the template, add an ID, insert into DB, call insert event
1329
+ // ****************************************
1330
+ const columns = [];
1331
+ const records = [];
1332
+ const input = protectJSON(i);
1333
+ each(input, (v, i) => {
1334
+ let nv;
1335
+ let o;
1336
+ if (T.isArray(v) && i === 0) {
1337
+ each(v, (av) => {
1338
+ columns.push(
1339
+ settings.forcePropertyCase === 'lower'
1340
+ ? av.toLowerCase()
1341
+ : settings.forcePropertyCase === 'upper'
1342
+ ? av.toUpperCase()
1343
+ : av,
1344
+ );
1345
+ });
1346
+ return true;
1347
+ }
1348
+ if (T.isArray(v)) {
1349
+ nv = {};
1350
+ each(v, (av, ai) => {
1351
+ nv[columns[ai]] = av;
1352
+ });
1353
+ v = nv;
1354
+ } else if (T.isObject(v) && settings.forcePropertyCase) {
1355
+ o = {};
1356
+
1357
+ eachin(v, (av, ai) => {
1358
+ o[
1359
+ settings.forcePropertyCase === 'lower'
1360
+ ? ai.toLowerCase()
1361
+ : settings.forcePropertyCase === 'upper'
1362
+ ? ai.toUpperCase()
1363
+ : ai
1364
+ ] = v[ai];
1365
+ });
1366
+ v = o;
1367
+ }
1368
+
1369
+ RC++;
1370
+ v.___id = `T${String(idpad + TC).slice(-6)}R${String(
1371
+ idpad + RC,
1372
+ ).slice(-6)}`;
1373
+ v.___s = true;
1374
+ records.push(v.___id);
1375
+ if (settings.template) {
1376
+ v = T.mergeObj(settings.template, v);
1377
+ }
1378
+ TOb.push(v);
1379
+
1380
+ ID[v.___id] = TOb.length - 1;
1381
+ if (
1382
+ settings.onInsert &&
1383
+ (runEvent || TAFFY.isUndefined(runEvent))
1384
+ ) {
1385
+ settings.onInsert.call(v);
1386
+ }
1387
+ DBI.dm(new Date());
1388
+ });
1389
+ return root(records);
1390
+ },
1391
+ sort(o) {
1392
+ // ****************************************
1393
+ // *
1394
+ // * Purpose: Change the sort order of the DB itself and reset the ID bucket
1395
+ // ****************************************
1396
+ TOb = orderByCol(TOb, o.split(','));
1397
+ ID = {};
1398
+ each(TOb, (r, i) => {
1399
+ ID[r.___id] = i;
1400
+ });
1401
+ DBI.dm(new Date());
1402
+ return true;
1403
+ },
1404
+ update(id, changes, runEvent) {
1405
+ // ****************************************
1406
+ // *
1407
+ // * Takes: the ID of record being changed and the changes
1408
+ // * Purpose: Update a record and change some or all values, call the on update method
1409
+ // ****************************************
1410
+
1411
+ const nc = {};
1412
+ let or;
1413
+ let nr;
1414
+ let tc;
1415
+ let hasChange;
1416
+ if (settings.forcePropertyCase) {
1417
+ eachin(changes, (v, p) => {
1418
+ nc[
1419
+ settings.forcePropertyCase === 'lower'
1420
+ ? p.toLowerCase()
1421
+ : settings.forcePropertyCase === 'upper'
1422
+ ? p.toUpperCase()
1423
+ : p
1424
+ ] = v;
1425
+ });
1426
+ changes = nc;
1427
+ }
1428
+
1429
+ or = TOb[ID[id]];
1430
+ nr = T.mergeObj(or, changes);
1431
+
1432
+ tc = {};
1433
+ hasChange = false;
1434
+ eachin(nr, (v, i) => {
1435
+ if (TAFFY.isUndefined(or[i]) || or[i] !== v) {
1436
+ tc[i] = v;
1437
+ hasChange = true;
1438
+ }
1439
+ });
1440
+ if (hasChange) {
1441
+ if (
1442
+ settings.onUpdate &&
1443
+ (runEvent || TAFFY.isUndefined(runEvent))
1444
+ ) {
1445
+ settings.onUpdate.call(nr, TOb[ID[id]], tc);
1446
+ }
1447
+ TOb[ID[id]] = nr;
1448
+ DBI.dm(new Date());
1449
+ }
1450
+ },
1451
+ remove(id) {
1452
+ // ****************************************
1453
+ // *
1454
+ // * Takes: the ID of record to be removed
1455
+ // * Purpose: remove a record, changes its ___s value to false
1456
+ // ****************************************
1457
+ TOb[ID[id]].___s = false;
1458
+ },
1459
+ removeCommit(runEvent) {
1460
+ let x;
1461
+ // ****************************************
1462
+ // *
1463
+ // *
1464
+ // * Purpose: loop over all records and remove records with ___s = false, call onRemove event, clear ID
1465
+ // ****************************************
1466
+ for (x = TOb.length - 1; x > -1; x--) {
1467
+ if (!TOb[x].___s) {
1468
+ if (
1469
+ settings.onRemove &&
1470
+ (runEvent || TAFFY.isUndefined(runEvent))
1471
+ ) {
1472
+ settings.onRemove.call(TOb[x]);
1473
+ }
1474
+ ID[TOb[x].___id] = undefined;
1475
+ TOb.splice(x, 1);
1476
+ }
1477
+ }
1478
+ ID = {};
1479
+ each(TOb, (r, i) => {
1480
+ ID[r.___id] = i;
1481
+ });
1482
+ DBI.dm(new Date());
1483
+ },
1484
+ query(context) {
1485
+ // ****************************************
1486
+ // *
1487
+ // * Takes: the context object for a query and either returns a cache result or a new query result
1488
+ // ****************************************
1489
+ let returnq;
1490
+ let cid;
1491
+ let results;
1492
+ let indexed;
1493
+ let limitq;
1494
+ let ni;
1495
+
1496
+ if (settings.cacheSize) {
1497
+ cid = '';
1498
+ each(context.filterRaw, (r) => {
1499
+ if (T.isFunction(r)) {
1500
+ cid = 'nocache';
1501
+ return TAFFY.EXIT;
1502
+ }
1503
+ });
1504
+ if (cid === '') {
1505
+ cid = makeCid(
1506
+ T.mergeObj(context, { q: false, run: false, sort: false }),
1507
+ );
1508
+ }
1509
+ }
1510
+ // Run a new query if there are no results or the run date has been cleared
1511
+ if (
1512
+ !context.results ||
1513
+ !context.run ||
1514
+ (context.run && DBI.dm() > context.run)
1515
+ ) {
1516
+ results = [];
1517
+
1518
+ // check Cache
1519
+
1520
+ if (settings.cacheSize && Cache[cid]) {
1521
+ Cache[cid].i = CacheCount++;
1522
+ return Cache[cid].results;
1523
+ }
1524
+ // if no filter, return DB
1525
+ if (context.q.length === 0 && context.index.length === 0) {
1526
+ each(TOb, (r) => {
1527
+ results.push(r);
1528
+ });
1529
+ returnq = results;
1530
+ } else {
1531
+ // use indexes
1532
+
1533
+ indexed = runIndexes(context.index);
1534
+
1535
+ // run filters
1536
+ each(indexed, (r) => {
1537
+ // Run filter to see if record matches query
1538
+ if (context.q.length === 0 || runFilters(r, context.q)) {
1539
+ results.push(r);
1540
+ }
1541
+ });
1542
+
1543
+ returnq = results;
1544
+ }
1545
+ } else {
1546
+ // If query exists and run has not been cleared return the cache results
1547
+ returnq = context.results;
1548
+ }
1549
+ // If a custom order array exists and the run has been clear or the sort has been cleared
1550
+ if (context.order.length > 0 && (!context.run || !context.sort)) {
1551
+ // order the results
1552
+ returnq = orderByCol(returnq, context.order);
1553
+ }
1554
+
1555
+ // If a limit on the number of results exists and it is less than the returned results, limit results
1556
+ if (
1557
+ returnq.length &&
1558
+ ((context.limit && context.limit < returnq.length) || context.start)
1559
+ ) {
1560
+ limitq = [];
1561
+ each(returnq, (r, i) => {
1562
+ if (!context.start || (context.start && i + 1 >= context.start)) {
1563
+ if (context.limit) {
1564
+ ni = context.start ? i + 1 - context.start : i;
1565
+ if (ni < context.limit) {
1566
+ limitq.push(r);
1567
+ } else if (ni > context.limit) {
1568
+ return TAFFY.EXIT;
1569
+ }
1570
+ } else {
1571
+ limitq.push(r);
1572
+ }
1573
+ }
1574
+ });
1575
+ returnq = limitq;
1576
+ }
1577
+
1578
+ // update cache
1579
+ if (settings.cacheSize && cid !== 'nocache') {
1580
+ CacheClear++;
1581
+
1582
+ setTimeout(() => {
1583
+ let bCounter;
1584
+ let nc;
1585
+ if (CacheClear >= settings.cacheSize * 2) {
1586
+ CacheClear = 0;
1587
+ bCounter = CacheCount - settings.cacheSize;
1588
+ nc = {};
1589
+ eachin((r, k) => {
1590
+ if (r.i >= bCounter) {
1591
+ nc[k] = r;
1592
+ }
1593
+ });
1594
+ Cache = nc;
1595
+ }
1596
+ }, 0);
1597
+
1598
+ Cache[cid] = { i: CacheCount++, results: returnq };
1599
+ }
1600
+ return returnq;
1601
+ },
1602
+ };
1603
+
1604
+ root = function () {
1605
+ let iAPI;
1606
+ let context;
1607
+ // ****************************************
1608
+ // *
1609
+ // * The root function that gets returned when a new DB is created
1610
+ // * Takes: unlimited filter arguments and creates filters to be run when a query is called
1611
+ // ****************************************
1612
+ // ****************************************
1613
+ // *
1614
+ // * iAPI is the the method collection valiable when a query has been started by calling dbname
1615
+ // * Certain methods are or are not avaliable once you have started a query such as insert -- you can only insert into root
1616
+ // ****************************************
1617
+ iAPI = TAFFY.mergeObj(TAFFY.mergeObj(API, { insert: undefined }), {
1618
+ getDBI() {
1619
+ return DBI;
1620
+ },
1621
+ getroot(c) {
1622
+ return root.call(c);
1623
+ },
1624
+ context(n) {
1625
+ // ****************************************
1626
+ // *
1627
+ // * The context contains all the information to manage a query including filters, limits, and sorts
1628
+ // ****************************************
1629
+ if (n) {
1630
+ context = TAFFY.mergeObj(
1631
+ context,
1632
+ n.hasOwnProperty('results')
1633
+ ? TAFFY.mergeObj(n, { run: new Date(), sort: new Date() })
1634
+ : n,
1635
+ );
1636
+ }
1637
+ return context;
1638
+ },
1639
+ extend: undefined,
1640
+ });
1641
+
1642
+ context =
1643
+ this && this.q
1644
+ ? this
1645
+ : {
1646
+ limit: false,
1647
+ start: false,
1648
+ q: [],
1649
+ filterRaw: [],
1650
+ index: [],
1651
+ order: [],
1652
+ results: false,
1653
+ run: null,
1654
+ sort: null,
1655
+ settings,
1656
+ };
1657
+ // ****************************************
1658
+ // *
1659
+ // * Call the query method to setup a new query
1660
+ // ****************************************
1661
+ each(sortArgs(arguments), (f) => {
1662
+ if (isIndexable(f)) {
1663
+ context.index.push(f);
1664
+ } else {
1665
+ context.q.push(returnFilter(f));
1666
+ }
1667
+ context.filterRaw.push(f);
1668
+ });
1669
+
1670
+ return iAPI;
1671
+ };
1672
+
1673
+ // ****************************************
1674
+ // *
1675
+ // * If new records have been passed on creation of the DB either as JSON or as an array/object, insert them
1676
+ // ****************************************
1677
+ TC++;
1678
+ if (d) {
1679
+ DBI.insert(d);
1680
+ }
1681
+
1682
+ root.insert = DBI.insert;
1683
+
1684
+ root.merge = function (i, key, runEvent) {
1685
+ const search = {};
1686
+ const finalSearch = [];
1687
+ const obj = {};
1688
+ runEvent = runEvent || false;
1689
+ key = key || 'id';
1690
+
1691
+ each(i, (o) => {
1692
+ let existingObject;
1693
+ search[key] = o[key];
1694
+ finalSearch.push(o[key]);
1695
+ existingObject = root(search).first();
1696
+ if (existingObject) {
1697
+ DBI.update(existingObject.___id, o, runEvent);
1698
+ } else {
1699
+ DBI.insert(o, runEvent);
1700
+ }
1701
+ });
1702
+
1703
+ obj[key] = finalSearch;
1704
+ return root(obj);
1705
+ };
1706
+
1707
+ root.TAFFY = true;
1708
+ root.sort = DBI.sort;
1709
+ // ****************************************
1710
+ // *
1711
+ // * These are the methods that can be accessed on off the root DB function. Example dbname.insert;
1712
+ // ****************************************
1713
+ root.settings = function (n) {
1714
+ // ****************************************
1715
+ // *
1716
+ // * Getting and setting for this DB's settings/events
1717
+ // ****************************************
1718
+ if (n) {
1719
+ settings = TAFFY.mergeObj(settings, n);
1720
+ if (n.template) {
1721
+ root().update(n.template);
1722
+ }
1723
+ }
1724
+ return settings;
1725
+ };
1726
+
1727
+ // ****************************************
1728
+ // *
1729
+ // * These are the methods that can be accessed on off the root DB function. Example dbname.insert;
1730
+ // ****************************************
1731
+ root.store = function (n) {
1732
+ // ****************************************
1733
+ // *
1734
+ // * Setup localstorage for this DB on a given name
1735
+ // * Pull data into the DB as needed
1736
+ // ****************************************
1737
+ let r = false;
1738
+ let i;
1739
+ if (localStorage) {
1740
+ if (n) {
1741
+ i = localStorage.getItem(`taffy_${n}`);
1742
+ if (i && i.length > 0) {
1743
+ root.insert(i);
1744
+ r = true;
1745
+ }
1746
+ if (TOb.length > 0) {
1747
+ setTimeout(() => {
1748
+ localStorage.setItem(
1749
+ `taffy_${settings.storageName}`,
1750
+ JSON.stringify(TOb),
1751
+ );
1752
+ });
1753
+ }
1754
+ }
1755
+ root.settings({ storageName: n });
1756
+ }
1757
+ return root;
1758
+ };
1759
+
1760
+ // ****************************************
1761
+ // *
1762
+ // * Return root on DB creation and start having fun
1763
+ // ****************************************
1764
+ return root;
1765
+ };
1766
+ // ****************************************
1767
+ // *
1768
+ // * Sets the global TAFFY object
1769
+ // ****************************************
1770
+ TAFFY = T;
1771
+
1772
+ // ****************************************
1773
+ // *
1774
+ // * Create public each method
1775
+ // *
1776
+ // ****************************************
1777
+ T.each = each;
1778
+
1779
+ // ****************************************
1780
+ // *
1781
+ // * Create public eachin method
1782
+ // *
1783
+ // ****************************************
1784
+ T.eachin = eachin;
1785
+ // ****************************************
1786
+ // *
1787
+ // * Create public extend method
1788
+ // * Add a custom method to the API
1789
+ // *
1790
+ // ****************************************
1791
+ T.extend = API.extend;
1792
+
1793
+ // ****************************************
1794
+ // *
1795
+ // * Creates TAFFY.EXIT value that can be returned to stop an each loop
1796
+ // *
1797
+ // ****************************************
1798
+ TAFFY.EXIT = 'TAFFYEXIT';
1799
+
1800
+ // ****************************************
1801
+ // *
1802
+ // * Create public utility mergeObj method
1803
+ // * Return a new object where items from obj2
1804
+ // * have replaced or been added to the items in
1805
+ // * obj1
1806
+ // * Purpose: Used to combine objs
1807
+ // *
1808
+ // ****************************************
1809
+ TAFFY.mergeObj = function (ob1, ob2) {
1810
+ const c = {};
1811
+ eachin(ob1, (v, n) => {
1812
+ c[n] = ob1[n];
1813
+ });
1814
+ eachin(ob2, (v, n) => {
1815
+ c[n] = ob2[n];
1816
+ });
1817
+ return c;
1818
+ };
1819
+
1820
+ // ****************************************
1821
+ // *
1822
+ // * Create public utility has method
1823
+ // * Returns true if a complex object, array
1824
+ // * or taffy collection contains the material
1825
+ // * provided in the second argument
1826
+ // * Purpose: Used to comare objects
1827
+ // *
1828
+ // ****************************************
1829
+ TAFFY.has = function (var1, var2) {
1830
+ let re = false;
1831
+ let n;
1832
+
1833
+ if (var1.TAFFY) {
1834
+ re = var1(var2);
1835
+ if (re.length > 0) {
1836
+ return true;
1837
+ }
1838
+ return false;
1839
+ }
1840
+ switch (T.typeOf(var1)) {
1841
+ case 'object':
1842
+ if (T.isObject(var2)) {
1843
+ eachin(var2, (v, n) => {
1844
+ if (
1845
+ re === true &&
1846
+ !T.isUndefined(var1[n]) &&
1847
+ var1.hasOwnProperty(n)
1848
+ ) {
1849
+ re = T.has(var1[n], var2[n]);
1850
+ } else {
1851
+ re = false;
1852
+ return TAFFY.EXIT;
1853
+ }
1854
+ });
1855
+ } else if (T.isArray(var2)) {
1856
+ each(var2, (v, n) => {
1857
+ re = T.has(var1, var2[n]);
1858
+ if (re) {
1859
+ return TAFFY.EXIT;
1860
+ }
1861
+ });
1862
+ } else if (T.isString(var2)) {
1863
+ if (!TAFFY.isUndefined(var1[var2])) {
1864
+ return true;
1865
+ }
1866
+ return false;
1867
+ }
1868
+ return re;
1869
+ case 'array':
1870
+ if (T.isObject(var2)) {
1871
+ each(var1, (v, i) => {
1872
+ re = T.has(var1[i], var2);
1873
+ if (re === true) {
1874
+ return TAFFY.EXIT;
1875
+ }
1876
+ });
1877
+ } else if (T.isArray(var2)) {
1878
+ each(var2, (v2, i2) => {
1879
+ each(var1, (v1, i1) => {
1880
+ re = T.has(var1[i1], var2[i2]);
1881
+ if (re === true) {
1882
+ return TAFFY.EXIT;
1883
+ }
1884
+ });
1885
+ if (re === true) {
1886
+ return TAFFY.EXIT;
1887
+ }
1888
+ });
1889
+ } else if (T.isString(var2) || T.isNumber(var2)) {
1890
+ re = false;
1891
+ for (n = 0; n < var1.length; n++) {
1892
+ re = T.has(var1[n], var2);
1893
+ if (re) {
1894
+ return true;
1895
+ }
1896
+ }
1897
+ }
1898
+ return re;
1899
+ case 'string':
1900
+ if (T.isString(var2) && var2 === var1) {
1901
+ return true;
1902
+ }
1903
+ break;
1904
+ default:
1905
+ if (T.typeOf(var1) === T.typeOf(var2) && var1 === var2) {
1906
+ return true;
1907
+ }
1908
+ break;
1909
+ }
1910
+
1911
+ return false;
1912
+ };
1913
+
1914
+ // ****************************************
1915
+ // *
1916
+ // * Create public utility hasAll method
1917
+ // * Returns true if a complex object, array
1918
+ // * or taffy collection contains the material
1919
+ // * provided in the call - for arrays it must
1920
+ // * contain all the material in each array item
1921
+ // * Purpose: Used to comare objects
1922
+ // *
1923
+ // ****************************************
1924
+ TAFFY.hasAll = function (var1, var2) {
1925
+ const T = TAFFY;
1926
+ let ar;
1927
+ if (T.isArray(var2)) {
1928
+ ar = true;
1929
+ each(var2, (v) => {
1930
+ ar = T.has(var1, v);
1931
+ if (ar === false) {
1932
+ return TAFFY.EXIT;
1933
+ }
1934
+ });
1935
+ return ar;
1936
+ }
1937
+ return T.has(var1, var2);
1938
+ };
1939
+
1940
+ // ****************************************
1941
+ // *
1942
+ // * typeOf Fixed in JavaScript as public utility
1943
+ // *
1944
+ // ****************************************
1945
+ TAFFY.typeOf = function (v) {
1946
+ let s = typeof v;
1947
+ if (s === 'object') {
1948
+ if (v) {
1949
+ if (
1950
+ typeof v.length === 'number' &&
1951
+ !v.propertyIsEnumerable('length')
1952
+ ) {
1953
+ s = 'array';
1954
+ }
1955
+ } else {
1956
+ s = 'null';
1957
+ }
1958
+ }
1959
+ return s;
1960
+ };
1961
+
1962
+ // ****************************************
1963
+ // *
1964
+ // * Create public utility getObjectKeys method
1965
+ // * Returns an array of an objects keys
1966
+ // * Purpose: Used to get the keys for an object
1967
+ // *
1968
+ // ****************************************
1969
+ TAFFY.getObjectKeys = function (ob) {
1970
+ const kA = [];
1971
+ eachin(ob, (n, h) => {
1972
+ kA.push(h);
1973
+ });
1974
+ kA.sort();
1975
+ return kA;
1976
+ };
1977
+
1978
+ // ****************************************
1979
+ // *
1980
+ // * Create public utility isSameArray
1981
+ // * Returns an array of an objects keys
1982
+ // * Purpose: Used to get the keys for an object
1983
+ // *
1984
+ // ****************************************
1985
+ TAFFY.isSameArray = function (ar1, ar2) {
1986
+ return !!(
1987
+ TAFFY.isArray(ar1) &&
1988
+ TAFFY.isArray(ar2) &&
1989
+ ar1.join(',') === ar2.join(',')
1990
+ );
1991
+ };
1992
+
1993
+ // ****************************************
1994
+ // *
1995
+ // * Create public utility isSameObject method
1996
+ // * Returns true if objects contain the same
1997
+ // * material or false if they do not
1998
+ // * Purpose: Used to comare objects
1999
+ // *
2000
+ // ****************************************
2001
+ TAFFY.isSameObject = function (ob1, ob2) {
2002
+ const T = TAFFY;
2003
+ let rv = true;
2004
+
2005
+ if (T.isObject(ob1) && T.isObject(ob2)) {
2006
+ if (T.isSameArray(T.getObjectKeys(ob1), T.getObjectKeys(ob2))) {
2007
+ eachin(ob1, (v, n) => {
2008
+ if (
2009
+ !(
2010
+ (T.isObject(ob1[n]) &&
2011
+ T.isObject(ob2[n]) &&
2012
+ T.isSameObject(ob1[n], ob2[n])) ||
2013
+ (T.isArray(ob1[n]) &&
2014
+ T.isArray(ob2[n]) &&
2015
+ T.isSameArray(ob1[n], ob2[n])) ||
2016
+ ob1[n] === ob2[n]
2017
+ )
2018
+ ) {
2019
+ rv = false;
2020
+ return TAFFY.EXIT;
2021
+ }
2022
+ });
2023
+ } else {
2024
+ rv = false;
2025
+ }
2026
+ } else {
2027
+ rv = false;
2028
+ }
2029
+ return rv;
2030
+ };
2031
+
2032
+ // ****************************************
2033
+ // *
2034
+ // * Create public utility is[DataType] methods
2035
+ // * Return true if obj is datatype, false otherwise
2036
+ // * Purpose: Used to determine if arguments are of certain data type
2037
+ // *
2038
+ // * mmikowski 2012-08-06 refactored to make much less "magical":
2039
+ // * fewer closures and passes jslint
2040
+ // *
2041
+ // ****************************************
2042
+
2043
+ typeList = [
2044
+ 'String',
2045
+ 'Number',
2046
+ 'Object',
2047
+ 'Array',
2048
+ 'Boolean',
2049
+ 'Null',
2050
+ 'Function',
2051
+ 'Undefined',
2052
+ ];
2053
+
2054
+ makeTest = function (thisKey) {
2055
+ return function (data) {
2056
+ return TAFFY.typeOf(data) === thisKey.toLowerCase();
2057
+ };
2058
+ };
2059
+
2060
+ for (idx = 0; idx < typeList.length; idx++) {
2061
+ typeKey = typeList[idx];
2062
+ TAFFY[`is${typeKey}`] = makeTest(typeKey);
2063
+ }
2064
+ }
2065
+ })();
2066
+
2067
+ if (typeof exports === 'object') {
2068
+ exports.taffy = TAFFY;
2069
+ }
2070
+ export default TAFFY;