utneque 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (431) hide show
  1. package/.editorconfig +10 -0
  2. package/.eslintrc.isomorphic.js +26 -0
  3. package/.eslintrc.js +86 -0
  4. package/.gitattributes +1 -0
  5. package/.github/workflows/ci.yml +33 -0
  6. package/.github/workflows/deploy-browser-cdn-candidate.yml +51 -0
  7. package/.github/workflows/deploy-releases.yml +178 -0
  8. package/.nvmrc +1 -0
  9. package/.prettierrc +7 -0
  10. package/.vscode/extensions.json +3 -0
  11. package/.vscode/launch.json +81 -0
  12. package/.vscode/settings.json +41 -0
  13. package/.yarn/plugins/@yarnpkg/plugin-constraints.cjs +52 -0
  14. package/.yarn/plugins/@yarnpkg/plugin-interactive-tools.cjs +546 -0
  15. package/.yarn/plugins/@yarnpkg/plugin-typescript.cjs +9 -0
  16. package/.yarn/plugins/@yarnpkg/plugin-workspace-tools.cjs +28 -0
  17. package/.yarn/releases/yarn-3.4.1.cjs +873 -0
  18. package/.yarnrc.yml +15 -0
  19. package/jest.config.js +18 -0
  20. package/package.json +59 -0
  21. package/packages/browser/.eslintrc.js +9 -0
  22. package/packages/browser/.lintstagedrc.js +1 -0
  23. package/packages/browser/ARCHITECTURE.md +48 -0
  24. package/packages/browser/LICENSE.MD +45 -0
  25. package/packages/browser/Makefile +64 -0
  26. package/packages/browser/README.md +227 -0
  27. package/packages/browser/e2e-tests/local-server.ts +28 -0
  28. package/packages/browser/e2e-tests/performance/ajs-perf-browser.test.ts +75 -0
  29. package/packages/browser/jest.config.js +15 -0
  30. package/packages/browser/jest.setup.js +10 -0
  31. package/packages/browser/package.json +106 -0
  32. package/packages/browser/qa/README.md +41 -0
  33. package/packages/browser/qa/__fixtures__/snippets.ts +148 -0
  34. package/packages/browser/qa/__tests__/backwards-compatibility.test.ts +180 -0
  35. package/packages/browser/qa/__tests__/destinations.test.ts +101 -0
  36. package/packages/browser/qa/__tests__/smoke.test.ts +170 -0
  37. package/packages/browser/qa/lib/benchmark.ts +36 -0
  38. package/packages/browser/qa/lib/browser.ts +28 -0
  39. package/packages/browser/qa/lib/jest-reporter.js +57 -0
  40. package/packages/browser/qa/lib/runner.ts +142 -0
  41. package/packages/browser/qa/lib/schema.ts +59 -0
  42. package/packages/browser/qa/lib/server.ts +54 -0
  43. package/packages/browser/qa/lib/stats.ts +52 -0
  44. package/packages/browser/scripts/build-prep.sh +7 -0
  45. package/packages/browser/scripts/ci.sh +15 -0
  46. package/packages/browser/scripts/release.js +121 -0
  47. package/packages/browser/scripts/release.sh +9 -0
  48. package/packages/browser/scripts/run.sh +8 -0
  49. package/packages/browser/src/browser/__tests__/analytics-lazy-init.integration.test.ts +51 -0
  50. package/packages/browser/src/browser/__tests__/analytics-pre-init.integration.test.ts +440 -0
  51. package/packages/browser/src/browser/__tests__/anon-id-and-reset.integration.test.ts +73 -0
  52. package/packages/browser/src/browser/__tests__/cdn.test.ts +53 -0
  53. package/packages/browser/src/browser/__tests__/csp-detection.test.ts +140 -0
  54. package/packages/browser/src/browser/__tests__/inspector.integration.test.ts +121 -0
  55. package/packages/browser/src/browser/__tests__/integration.test.ts +1213 -0
  56. package/packages/browser/src/browser/__tests__/integrations.integration.test.ts +260 -0
  57. package/packages/browser/src/browser/__tests__/page-enrichment.integration.test.ts +216 -0
  58. package/packages/browser/src/browser/__tests__/query-string.integration.test.ts +116 -0
  59. package/packages/browser/src/browser/__tests__/standalone-analytics.test.ts +303 -0
  60. package/packages/browser/src/browser/__tests__/standalone-errors.test.ts +136 -0
  61. package/packages/browser/src/browser/__tests__/standalone.test.ts +97 -0
  62. package/packages/browser/src/browser/__tests__/typedef-tests/analytics-browser.ts +150 -0
  63. package/packages/browser/src/browser/__tests__/update-cdn-settings.test.ts +71 -0
  64. package/packages/browser/src/browser/browser-umd.ts +19 -0
  65. package/packages/browser/src/browser/index.ts +486 -0
  66. package/packages/browser/src/browser/standalone-analytics.ts +62 -0
  67. package/packages/browser/src/browser/standalone-interface.ts +11 -0
  68. package/packages/browser/src/browser/standalone.ts +92 -0
  69. package/packages/browser/src/core/__tests__/track-form.test.ts +193 -0
  70. package/packages/browser/src/core/__tests__/track-link.test.ts +252 -0
  71. package/packages/browser/src/core/analytics/__tests__/integration.test.ts +334 -0
  72. package/packages/browser/src/core/analytics/__tests__/test-plugins.ts +94 -0
  73. package/packages/browser/src/core/analytics/index.ts +672 -0
  74. package/packages/browser/src/core/analytics/interfaces.ts +100 -0
  75. package/packages/browser/src/core/arguments-resolver/__tests__/index.test.ts +524 -0
  76. package/packages/browser/src/core/arguments-resolver/index.ts +200 -0
  77. package/packages/browser/src/core/auto-track.ts +152 -0
  78. package/packages/browser/src/core/buffer/__tests__/index.test.ts +455 -0
  79. package/packages/browser/src/core/buffer/index.ts +371 -0
  80. package/packages/browser/src/core/callback/index.ts +1 -0
  81. package/packages/browser/src/core/connection/__tests__/index.test.ts +25 -0
  82. package/packages/browser/src/core/connection/index.ts +13 -0
  83. package/packages/browser/src/core/constants/index.ts +1 -0
  84. package/packages/browser/src/core/context/__tests__/index.test.ts +201 -0
  85. package/packages/browser/src/core/context/index.ts +21 -0
  86. package/packages/browser/src/core/environment/index.ts +7 -0
  87. package/packages/browser/src/core/events/__tests__/index.test.ts +450 -0
  88. package/packages/browser/src/core/events/index.ts +280 -0
  89. package/packages/browser/src/core/events/interfaces.ts +36 -0
  90. package/packages/browser/src/core/inspector/index.ts +14 -0
  91. package/packages/browser/src/core/page/__tests__/index.test.ts +130 -0
  92. package/packages/browser/src/core/page/add-page-context.ts +33 -0
  93. package/packages/browser/src/core/page/get-page-context.ts +140 -0
  94. package/packages/browser/src/core/page/index.ts +2 -0
  95. package/packages/browser/src/core/plugin/index.ts +12 -0
  96. package/packages/browser/src/core/query-string/__tests__/gracefulDecodeURIComponent.test.ts +17 -0
  97. package/packages/browser/src/core/query-string/__tests__/index.test.ts +149 -0
  98. package/packages/browser/src/core/query-string/__tests__/pickPrefix.test.ts +31 -0
  99. package/packages/browser/src/core/query-string/__tests__/useQueryString.test.ts +60 -0
  100. package/packages/browser/src/core/query-string/gracefulDecodeURIComponent.ts +16 -0
  101. package/packages/browser/src/core/query-string/index.ts +64 -0
  102. package/packages/browser/src/core/query-string/pickPrefix.ts +20 -0
  103. package/packages/browser/src/core/queue/__tests__/event-queue.test.ts +82 -0
  104. package/packages/browser/src/core/queue/event-queue.ts +22 -0
  105. package/packages/browser/src/core/session/__tests__/index.test.ts +41 -0
  106. package/packages/browser/src/core/session/index.ts +107 -0
  107. package/packages/browser/src/core/stats/__tests__/index.test.ts +15 -0
  108. package/packages/browser/src/core/stats/__tests__/remote-metrics.test.ts +189 -0
  109. package/packages/browser/src/core/stats/index.ts +15 -0
  110. package/packages/browser/src/core/stats/remote-metrics.ts +144 -0
  111. package/packages/browser/src/core/storage/__tests__/cookieStorage.test.ts +58 -0
  112. package/packages/browser/src/core/storage/__tests__/localStorage.test.ts +70 -0
  113. package/packages/browser/src/core/storage/__tests__/test-helpers.ts +26 -0
  114. package/packages/browser/src/core/storage/__tests__/universalStorage.test.ts +167 -0
  115. package/packages/browser/src/core/storage/cookieStorage.ts +80 -0
  116. package/packages/browser/src/core/storage/index.ts +64 -0
  117. package/packages/browser/src/core/storage/localStorage.ts +45 -0
  118. package/packages/browser/src/core/storage/memoryStorage.ts +22 -0
  119. package/packages/browser/src/core/storage/settings.ts +23 -0
  120. package/packages/browser/src/core/storage/types.ts +49 -0
  121. package/packages/browser/src/core/storage/universalStorage.ts +78 -0
  122. package/packages/browser/src/core/user/__tests__/index.test.ts +922 -0
  123. package/packages/browser/src/core/user/__tests__/migrate.test.ts +101 -0
  124. package/packages/browser/src/core/user/__tests__/session.test.ts +136 -0
  125. package/packages/browser/src/core/user/__tests__/tld.test.ts +36 -0
  126. package/packages/browser/src/core/user/index.ts +399 -0
  127. package/packages/browser/src/core/user/migrate.ts +126 -0
  128. package/packages/browser/src/core/user/tld.ts +65 -0
  129. package/packages/browser/src/core/user/vendor/crypto-es/LICENSE +53 -0
  130. package/packages/browser/src/core/user/vendor/crypto-es/lib/aes.ts +302 -0
  131. package/packages/browser/src/core/user/vendor/crypto-es/lib/cipher-core.ts +922 -0
  132. package/packages/browser/src/core/user/vendor/crypto-es/lib/core.ts +806 -0
  133. package/packages/browser/src/core/user/vendor/crypto-es/lib/enc-base64.ts +110 -0
  134. package/packages/browser/src/core/user/vendor/crypto-es/lib/evpkdf.ts +110 -0
  135. package/packages/browser/src/core/user/vendor/crypto-es/lib/md5.ts +238 -0
  136. package/packages/browser/src/core/user/vendor/readme.md +7 -0
  137. package/packages/browser/src/generated/__tests__/version.test.ts +18 -0
  138. package/packages/browser/src/generated/version.ts +2 -0
  139. package/packages/browser/src/index.ts +13 -0
  140. package/packages/browser/src/lib/__tests__/embedded-write-key.test.ts +15 -0
  141. package/packages/browser/src/lib/__tests__/fetch.test.ts +35 -0
  142. package/packages/browser/src/lib/__tests__/get-process-env.test.ts +5 -0
  143. package/packages/browser/src/lib/__tests__/group-by.test.ts +96 -0
  144. package/packages/browser/src/lib/__tests__/is-plan-event-enabled.test.ts +36 -0
  145. package/packages/browser/src/lib/__tests__/is-thenable.test.ts +39 -0
  146. package/packages/browser/src/lib/__tests__/merged-options.test.ts +123 -0
  147. package/packages/browser/src/lib/__tests__/on-page-change.test.ts +74 -0
  148. package/packages/browser/src/lib/__tests__/parse-cdn.test.ts +88 -0
  149. package/packages/browser/src/lib/__tests__/pick.test.ts +34 -0
  150. package/packages/browser/src/lib/__tests__/pick.typedef.ts +39 -0
  151. package/packages/browser/src/lib/bind-all.ts +19 -0
  152. package/packages/browser/src/lib/browser-polyfill.ts +23 -0
  153. package/packages/browser/src/lib/client-hints/__tests__/index.test.ts +66 -0
  154. package/packages/browser/src/lib/client-hints/index.ts +16 -0
  155. package/packages/browser/src/lib/client-hints/interfaces.ts +42 -0
  156. package/packages/browser/src/lib/create-deferred.ts +16 -0
  157. package/packages/browser/src/lib/csp-detection.ts +8 -0
  158. package/packages/browser/src/lib/embedded-write-key.ts +24 -0
  159. package/packages/browser/src/lib/fetch.ts +10 -0
  160. package/packages/browser/src/lib/get-global.ts +16 -0
  161. package/packages/browser/src/lib/get-process-env.ts +11 -0
  162. package/packages/browser/src/lib/global-analytics-helper.ts +31 -0
  163. package/packages/browser/src/lib/group-by.ts +30 -0
  164. package/packages/browser/src/lib/is-plan-event-enabled.ts +20 -0
  165. package/packages/browser/src/lib/is-thenable.ts +9 -0
  166. package/packages/browser/src/lib/load-script.ts +66 -0
  167. package/packages/browser/src/lib/merged-options.ts +46 -0
  168. package/packages/browser/src/lib/on-page-change.ts +29 -0
  169. package/packages/browser/src/lib/p-while.ts +12 -0
  170. package/packages/browser/src/lib/parse-cdn.ts +56 -0
  171. package/packages/browser/src/lib/pick.ts +28 -0
  172. package/packages/browser/src/lib/priority-queue/__tests__/backoff.test.ts +23 -0
  173. package/packages/browser/src/lib/priority-queue/__tests__/index.test.ts +158 -0
  174. package/packages/browser/src/lib/priority-queue/__tests__/persisted.test.ts +228 -0
  175. package/packages/browser/src/lib/priority-queue/backoff.ts +24 -0
  176. package/packages/browser/src/lib/priority-queue/index.ts +6 -0
  177. package/packages/browser/src/lib/priority-queue/persisted.ts +127 -0
  178. package/packages/browser/src/lib/sleep.ts +4 -0
  179. package/packages/browser/src/lib/to-facade.ts +53 -0
  180. package/packages/browser/src/lib/version-type.ts +10 -0
  181. package/packages/browser/src/node/__tests__/node-integration.test.ts +19 -0
  182. package/packages/browser/src/node/index.ts +36 -0
  183. package/packages/browser/src/node/node.browser.ts +7 -0
  184. package/packages/browser/src/plugins/ajs-destination/__tests__/index.test.ts +834 -0
  185. package/packages/browser/src/plugins/ajs-destination/index.ts +392 -0
  186. package/packages/browser/src/plugins/ajs-destination/loader.ts +129 -0
  187. package/packages/browser/src/plugins/ajs-destination/types.ts +44 -0
  188. package/packages/browser/src/plugins/ajs-destination/utils.ts +32 -0
  189. package/packages/browser/src/plugins/analytics-node/__tests__/index.test.ts +69 -0
  190. package/packages/browser/src/plugins/analytics-node/index.ts +67 -0
  191. package/packages/browser/src/plugins/env-enrichment/__tests__/index.test.ts +421 -0
  192. package/packages/browser/src/plugins/env-enrichment/index.ts +208 -0
  193. package/packages/browser/src/plugins/hightouchio/__tests__/batched-dispatcher.test.ts +299 -0
  194. package/packages/browser/src/plugins/hightouchio/__tests__/index.test.ts +317 -0
  195. package/packages/browser/src/plugins/hightouchio/__tests__/normalize.test.ts +181 -0
  196. package/packages/browser/src/plugins/hightouchio/__tests__/retries.test.ts +82 -0
  197. package/packages/browser/src/plugins/hightouchio/batched-dispatcher.ts +127 -0
  198. package/packages/browser/src/plugins/hightouchio/fetch-dispatcher.ts +27 -0
  199. package/packages/browser/src/plugins/hightouchio/index.ts +147 -0
  200. package/packages/browser/src/plugins/hightouchio/normalize.ts +71 -0
  201. package/packages/browser/src/plugins/hightouchio/schedule-flush.ts +58 -0
  202. package/packages/browser/src/plugins/legacy-video-plugins/__tests__/index.test.ts +48 -0
  203. package/packages/browser/src/plugins/legacy-video-plugins/index.ts +16 -0
  204. package/packages/browser/src/plugins/middleware/__tests__/index.test.ts +268 -0
  205. package/packages/browser/src/plugins/middleware/index.ts +131 -0
  206. package/packages/browser/src/plugins/remote-loader/__tests__/index.test.ts +943 -0
  207. package/packages/browser/src/plugins/remote-loader/index.ts +256 -0
  208. package/packages/browser/src/plugins/remote-middleware/__tests__/index.test.ts +116 -0
  209. package/packages/browser/src/plugins/remote-middleware/index.ts +44 -0
  210. package/packages/browser/src/plugins/routing-middleware/__tests__/index.test.ts +64 -0
  211. package/packages/browser/src/plugins/routing-middleware/index.ts +37 -0
  212. package/packages/browser/src/plugins/schema-filter/__tests__/index.test.ts +520 -0
  213. package/packages/browser/src/plugins/schema-filter/index.ts +90 -0
  214. package/packages/browser/src/plugins/validation/__tests__/index.test.ts +78 -0
  215. package/packages/browser/src/plugins/validation/index.ts +44 -0
  216. package/packages/browser/src/test-helpers/browser-storage.ts +75 -0
  217. package/packages/browser/src/test-helpers/factories.ts +18 -0
  218. package/packages/browser/src/test-helpers/fetch-parse.ts +8 -0
  219. package/packages/browser/src/test-helpers/fixtures/cdn-settings.ts +301 -0
  220. package/packages/browser/src/test-helpers/fixtures/classic-destination.ts +25 -0
  221. package/packages/browser/src/test-helpers/fixtures/client-hints.ts +28 -0
  222. package/packages/browser/src/test-helpers/fixtures/create-fetch-method.ts +30 -0
  223. package/packages/browser/src/test-helpers/fixtures/index.ts +4 -0
  224. package/packages/browser/src/test-helpers/fixtures/page-context.ts +11 -0
  225. package/packages/browser/src/test-helpers/test-writekeys.ts +5 -0
  226. package/packages/browser/src/test-helpers/type-assertions.ts +11 -0
  227. package/packages/browser/src/tester/__fixtures__/hightouch-snippet.ts +64 -0
  228. package/packages/browser/src/tester/__fixtures__/index.html +8 -0
  229. package/packages/browser/src/tester/ajs-perf.ts +30 -0
  230. package/packages/browser/src/tester/ajs-tester.ts +119 -0
  231. package/packages/browser/src/tester/server.js +16 -0
  232. package/packages/browser/tsconfig.build.json +9 -0
  233. package/packages/browser/tsconfig.json +13 -0
  234. package/packages/browser/webpack.config.js +106 -0
  235. package/packages/config/package.json +10 -0
  236. package/packages/config/src/index.js +4 -0
  237. package/packages/config/src/jest/config.js +50 -0
  238. package/packages/config/src/jest/get-module-map.js +34 -0
  239. package/packages/config/src/lint-staged/config.js +4 -0
  240. package/packages/config-webpack/package.json +20 -0
  241. package/packages/config-webpack/webpack.config.common.js +75 -0
  242. package/packages/consent/consent-tools/.eslintrc.js +7 -0
  243. package/packages/consent/consent-tools/.lintstagedrc.js +1 -0
  244. package/packages/consent/consent-tools/LICENSE +45 -0
  245. package/packages/consent/consent-tools/README.md +104 -0
  246. package/packages/consent/consent-tools/jest.config.js +6 -0
  247. package/packages/consent/consent-tools/jest.setup.js +4 -0
  248. package/packages/consent/consent-tools/package.json +48 -0
  249. package/packages/consent/consent-tools/src/domain/__tests__/assertions/integrations-assertions.ts +37 -0
  250. package/packages/consent/consent-tools/src/domain/__tests__/consent-stamping.test.ts +45 -0
  251. package/packages/consent/consent-tools/src/domain/__tests__/create-wrapper.test.ts +816 -0
  252. package/packages/consent/consent-tools/src/domain/__tests__/typedef-tests.ts +21 -0
  253. package/packages/consent/consent-tools/src/domain/consent-changed.ts +51 -0
  254. package/packages/consent/consent-tools/src/domain/consent-stamping.ts +19 -0
  255. package/packages/consent/consent-tools/src/domain/create-wrapper.ts +238 -0
  256. package/packages/consent/consent-tools/src/domain/get-initialized-analytics.ts +25 -0
  257. package/packages/consent/consent-tools/src/domain/load-cancellation.ts +31 -0
  258. package/packages/consent/consent-tools/src/domain/validation/__tests__/options-validators.test.ts +77 -0
  259. package/packages/consent/consent-tools/src/domain/validation/__tests__/validation-error.test.ts +15 -0
  260. package/packages/consent/consent-tools/src/domain/validation/common-validators.ts +19 -0
  261. package/packages/consent/consent-tools/src/domain/validation/index.ts +1 -0
  262. package/packages/consent/consent-tools/src/domain/validation/options-validators.ts +74 -0
  263. package/packages/consent/consent-tools/src/domain/validation/validation-error.ts +11 -0
  264. package/packages/consent/consent-tools/src/index.ts +16 -0
  265. package/packages/consent/consent-tools/src/types/errors.ts +14 -0
  266. package/packages/consent/consent-tools/src/types/index.ts +3 -0
  267. package/packages/consent/consent-tools/src/types/settings.ts +121 -0
  268. package/packages/consent/consent-tools/src/types/wrapper.ts +107 -0
  269. package/packages/consent/consent-tools/src/utils/index.ts +4 -0
  270. package/packages/consent/consent-tools/src/utils/pick.ts +18 -0
  271. package/packages/consent/consent-tools/src/utils/pipe.ts +14 -0
  272. package/packages/consent/consent-tools/src/utils/resolve-when.ts +32 -0
  273. package/packages/consent/consent-tools/src/utils/uniq.ts +4 -0
  274. package/packages/consent/consent-tools/tsconfig.build.json +9 -0
  275. package/packages/consent/consent-tools/tsconfig.json +12 -0
  276. package/packages/consent/consent-wrapper-onetrust/.eslintrc.js +7 -0
  277. package/packages/consent/consent-wrapper-onetrust/.lintstagedrc.js +1 -0
  278. package/packages/consent/consent-wrapper-onetrust/LICENSE +45 -0
  279. package/packages/consent/consent-wrapper-onetrust/README.md +125 -0
  280. package/packages/consent/consent-wrapper-onetrust/img/onetrust-cat-id.jpg +0 -0
  281. package/packages/consent/consent-wrapper-onetrust/img/onetrust-popup.jpg +0 -0
  282. package/packages/consent/consent-wrapper-onetrust/jest.config.js +6 -0
  283. package/packages/consent/consent-wrapper-onetrust/jest.setup.js +4 -0
  284. package/packages/consent/consent-wrapper-onetrust/package.json +60 -0
  285. package/packages/consent/consent-wrapper-onetrust/src/domain/__tests__/wrapper.test.ts +151 -0
  286. package/packages/consent/consent-wrapper-onetrust/src/domain/wrapper.ts +61 -0
  287. package/packages/consent/consent-wrapper-onetrust/src/index.ts +6 -0
  288. package/packages/consent/consent-wrapper-onetrust/src/index.umd.ts +11 -0
  289. package/packages/consent/consent-wrapper-onetrust/src/lib/__tests__/onetrust-api.test.ts +181 -0
  290. package/packages/consent/consent-wrapper-onetrust/src/lib/onetrust-api.ts +155 -0
  291. package/packages/consent/consent-wrapper-onetrust/src/lib/validation/index.ts +1 -0
  292. package/packages/consent/consent-wrapper-onetrust/src/lib/validation/onetrust-api-error.ts +11 -0
  293. package/packages/consent/consent-wrapper-onetrust/src/test-helpers/mocks.ts +23 -0
  294. package/packages/consent/consent-wrapper-onetrust/src/test-helpers/onetrust-globals.d.ts +11 -0
  295. package/packages/consent/consent-wrapper-onetrust/src/test-helpers/utils.ts +3 -0
  296. package/packages/consent/consent-wrapper-onetrust/tsconfig.build.json +9 -0
  297. package/packages/consent/consent-wrapper-onetrust/tsconfig.json +11 -0
  298. package/packages/consent/consent-wrapper-onetrust/webpack.config.js +25 -0
  299. package/packages/core/.eslintrc.js +4 -0
  300. package/packages/core/.lintstagedrc.js +1 -0
  301. package/packages/core/LICENSE.MD +45 -0
  302. package/packages/core/README.md +3 -0
  303. package/packages/core/jest.config.js +5 -0
  304. package/packages/core/jest.setup.js +10 -0
  305. package/packages/core/package.json +40 -0
  306. package/packages/core/src/analytics/__tests__/dispatch.test.ts +95 -0
  307. package/packages/core/src/analytics/dispatch.ts +58 -0
  308. package/packages/core/src/analytics/index.ts +11 -0
  309. package/packages/core/src/callback/__tests__/index.test.ts +85 -0
  310. package/packages/core/src/callback/index.ts +51 -0
  311. package/packages/core/src/context/index.ts +123 -0
  312. package/packages/core/src/emitter/__tests__/emitter.test.ts +74 -0
  313. package/packages/core/src/emitter/index.ts +65 -0
  314. package/packages/core/src/emitter/interface.ts +31 -0
  315. package/packages/core/src/events/__tests__/index.test.ts +394 -0
  316. package/packages/core/src/events/index.ts +280 -0
  317. package/packages/core/src/events/interfaces.ts +475 -0
  318. package/packages/core/src/index.ts +19 -0
  319. package/packages/core/src/logger/__tests__/index.test.ts +66 -0
  320. package/packages/core/src/logger/index.ts +74 -0
  321. package/packages/core/src/plugins/index.ts +43 -0
  322. package/packages/core/src/priority-queue/__tests__/backoff.test.ts +23 -0
  323. package/packages/core/src/priority-queue/__tests__/index.test.ts +158 -0
  324. package/packages/core/src/priority-queue/backoff.ts +24 -0
  325. package/packages/core/src/priority-queue/index.ts +103 -0
  326. package/packages/core/src/queue/__tests__/event-queue.test.ts +678 -0
  327. package/packages/core/src/queue/__tests__/extension-flushing.test.ts +416 -0
  328. package/packages/core/src/queue/delivery.ts +73 -0
  329. package/packages/core/src/queue/event-queue.ts +318 -0
  330. package/packages/core/src/stats/__tests__/index.test.ts +103 -0
  331. package/packages/core/src/stats/index.ts +88 -0
  332. package/packages/core/src/task/__tests__/task-group.test.ts +26 -0
  333. package/packages/core/src/task/task-group.ts +31 -0
  334. package/packages/core/src/user/index.ts +7 -0
  335. package/packages/core/src/utils/__tests__/group-by.test.ts +96 -0
  336. package/packages/core/src/utils/__tests__/is-plain-object.test.ts +27 -0
  337. package/packages/core/src/utils/__tests__/is-thenable.test.ts +39 -0
  338. package/packages/core/src/utils/bind-all.ts +19 -0
  339. package/packages/core/src/utils/get-global.ts +17 -0
  340. package/packages/core/src/utils/group-by.ts +30 -0
  341. package/packages/core/src/utils/has-properties.ts +7 -0
  342. package/packages/core/src/utils/is-plain-object.ts +26 -0
  343. package/packages/core/src/utils/is-thenable.ts +9 -0
  344. package/packages/core/src/utils/p-while.ts +12 -0
  345. package/packages/core/src/utils/pick.ts +8 -0
  346. package/packages/core/src/utils/ts-helpers.ts +13 -0
  347. package/packages/core/src/validation/__tests__/assertions.test.ts +155 -0
  348. package/packages/core/src/validation/assertions.ts +72 -0
  349. package/packages/core/src/validation/errors.ts +8 -0
  350. package/packages/core/src/validation/helpers.ts +23 -0
  351. package/packages/core/test-helpers/index.ts +2 -0
  352. package/packages/core/test-helpers/test-ctx.ts +7 -0
  353. package/packages/core/test-helpers/test-event-queue.ts +7 -0
  354. package/packages/core/tsconfig.build.json +9 -0
  355. package/packages/core/tsconfig.json +11 -0
  356. package/packages/node/.eslintrc.js +7 -0
  357. package/packages/node/.lintstagedrc.js +1 -0
  358. package/packages/node/LICENSE +45 -0
  359. package/packages/node/README.md +138 -0
  360. package/packages/node/jest.config.js +5 -0
  361. package/packages/node/jest.setup.js +4 -0
  362. package/packages/node/package.json +50 -0
  363. package/packages/node/scripts/version.sh +11 -0
  364. package/packages/node/src/__tests__/callback.test.ts +47 -0
  365. package/packages/node/src/__tests__/disable.integration.test.ts +42 -0
  366. package/packages/node/src/__tests__/emitter.integration.test.ts +45 -0
  367. package/packages/node/src/__tests__/graceful-shutdown-integration.test.ts +244 -0
  368. package/packages/node/src/__tests__/http-client.integration.test.ts +69 -0
  369. package/packages/node/src/__tests__/http-integration.test.ts +362 -0
  370. package/packages/node/src/__tests__/integration.test.ts +357 -0
  371. package/packages/node/src/__tests__/plugins.test.ts +16 -0
  372. package/packages/node/src/__tests__/settings.test.ts +9 -0
  373. package/packages/node/src/__tests__/test-helpers/assert-shape/http-request-event.ts +13 -0
  374. package/packages/node/src/__tests__/test-helpers/assert-shape/index.ts +2 -0
  375. package/packages/node/src/__tests__/test-helpers/assert-shape/segment-http-api.ts +43 -0
  376. package/packages/node/src/__tests__/test-helpers/create-test-analytics.ts +42 -0
  377. package/packages/node/src/__tests__/test-helpers/factories.ts +17 -0
  378. package/packages/node/src/__tests__/test-helpers/is-valid-date.ts +6 -0
  379. package/packages/node/src/__tests__/test-helpers/resolve-ctx.ts +19 -0
  380. package/packages/node/src/__tests__/test-helpers/resolve-emitter.ts +11 -0
  381. package/packages/node/src/__tests__/test-helpers/sleep.ts +3 -0
  382. package/packages/node/src/__tests__/test-helpers/test-plugin.ts +16 -0
  383. package/packages/node/src/__tests__/typedef-tests.ts +120 -0
  384. package/packages/node/src/app/analytics-node.ts +299 -0
  385. package/packages/node/src/app/context.ts +11 -0
  386. package/packages/node/src/app/dispatch-emit.ts +42 -0
  387. package/packages/node/src/app/emitter.ts +23 -0
  388. package/packages/node/src/app/event-factory.ts +20 -0
  389. package/packages/node/src/app/event-queue.ts +23 -0
  390. package/packages/node/src/app/settings.ts +49 -0
  391. package/packages/node/src/app/types/index.ts +3 -0
  392. package/packages/node/src/app/types/params.ts +76 -0
  393. package/packages/node/src/app/types/plugin.ts +5 -0
  394. package/packages/node/src/app/types/segment-event.ts +7 -0
  395. package/packages/node/src/generated/version.ts +2 -0
  396. package/packages/node/src/index.ts +26 -0
  397. package/packages/node/src/lib/__tests__/abort.test.ts +54 -0
  398. package/packages/node/src/lib/__tests__/create-url.test.ts +35 -0
  399. package/packages/node/src/lib/__tests__/env.test.ts +52 -0
  400. package/packages/node/src/lib/__tests__/get-message-id.test.ts +21 -0
  401. package/packages/node/src/lib/abort.ts +77 -0
  402. package/packages/node/src/lib/base-64-encode.ts +8 -0
  403. package/packages/node/src/lib/create-url.ts +11 -0
  404. package/packages/node/src/lib/env.ts +45 -0
  405. package/packages/node/src/lib/extract-promise-parts.ts +21 -0
  406. package/packages/node/src/lib/fetch.ts +16 -0
  407. package/packages/node/src/lib/get-message-id.ts +10 -0
  408. package/packages/node/src/lib/http-client.ts +95 -0
  409. package/packages/node/src/lib/uuid.ts +1 -0
  410. package/packages/node/src/plugins/segmentio/__tests__/methods.test.ts +223 -0
  411. package/packages/node/src/plugins/segmentio/__tests__/publisher.test.ts +411 -0
  412. package/packages/node/src/plugins/segmentio/context-batch.ts +71 -0
  413. package/packages/node/src/plugins/segmentio/index.ts +66 -0
  414. package/packages/node/src/plugins/segmentio/publisher.ts +265 -0
  415. package/packages/node/tsconfig.build.json +9 -0
  416. package/packages/node/tsconfig.json +10 -0
  417. package/packages/test-helpers/.eslintrc.js +7 -0
  418. package/packages/test-helpers/.lintstagedrc.js +1 -0
  419. package/packages/test-helpers/jest.config.js +3 -0
  420. package/packages/test-helpers/package.json +26 -0
  421. package/packages/test-helpers/src/analytics/cdn-settings-builder.ts +79 -0
  422. package/packages/test-helpers/src/analytics/index.ts +1 -0
  423. package/packages/test-helpers/src/index.ts +2 -0
  424. package/packages/test-helpers/src/utils/index.ts +1 -0
  425. package/packages/test-helpers/src/utils/sleep.ts +4 -0
  426. package/packages/test-helpers/tsconfig.build.json +9 -0
  427. package/packages/test-helpers/tsconfig.json +11 -0
  428. package/tsconfig.json +21 -0
  429. package/turbo.json +39 -0
  430. package/typings/get-monorepo-packages.d.ts +9 -0
  431. package/typings/spawn.d.ts +10 -0
@@ -0,0 +1,31 @@
1
+ import { HtEventsSnippet } from '../browser/standalone-interface'
2
+
3
+ /**
4
+ * Stores the global window analytics key
5
+ */
6
+ let _globalAnalyticsKey = 'htevents'
7
+
8
+ /**
9
+ * Gets the global analytics/buffer
10
+ * @param key name of the window property where the buffer is stored (default: analytics)
11
+ * @returns HtEventsSnippet
12
+ */
13
+ export function getGlobalAnalytics(): HtEventsSnippet | undefined {
14
+ return (window as any)[_globalAnalyticsKey]
15
+ }
16
+
17
+ /**
18
+ * Replaces the global window key for the analytics/buffer object
19
+ * @param key key name
20
+ */
21
+ export function setGlobalAnalyticsKey(key: string) {
22
+ _globalAnalyticsKey = key
23
+ }
24
+
25
+ /**
26
+ * Sets the global analytics object
27
+ * @param analytics analytics snippet
28
+ */
29
+ export function setGlobalAnalytics(analytics: HtEventsSnippet): void {
30
+ ;(window as any)[_globalAnalyticsKey] = analytics
31
+ }
@@ -0,0 +1,30 @@
1
+ type Grouper<T> = (obj: T) => string | number
2
+
3
+ export function groupBy<T>(
4
+ collection: T[],
5
+ grouper: keyof T | Grouper<T>
6
+ ): Record<string, T[]> {
7
+ const results: Record<string, T[]> = {}
8
+
9
+ collection.forEach((item) => {
10
+ let key: string | number | undefined = undefined
11
+
12
+ if (typeof grouper === 'string') {
13
+ const suggestedKey = item[grouper]
14
+ key =
15
+ typeof suggestedKey !== 'string'
16
+ ? JSON.stringify(suggestedKey)
17
+ : suggestedKey
18
+ } else if (grouper instanceof Function) {
19
+ key = grouper(item)
20
+ }
21
+
22
+ if (key === undefined) {
23
+ return
24
+ }
25
+
26
+ results[key] = [...(results[key] ?? []), item]
27
+ })
28
+
29
+ return results
30
+ }
@@ -0,0 +1,20 @@
1
+ import { PlanEvent, TrackPlan } from '../core/events/interfaces'
2
+
3
+ /**
4
+ * Determines whether a track event is allowed to be sent based on the
5
+ * user's tracking plan.
6
+ * If the user does not have a tracking plan or the event is allowed based
7
+ * on the tracking plan configuration, returns true.
8
+ */
9
+ export function isPlanEventEnabled(
10
+ plan: TrackPlan | undefined,
11
+ planEvent: PlanEvent | undefined
12
+ ): boolean {
13
+ // Always prioritize the event's `enabled` status
14
+ if (typeof planEvent?.enabled === 'boolean') {
15
+ return planEvent.enabled
16
+ }
17
+
18
+ // Assume absence of a tracking plan means events are enabled
19
+ return plan?.__default?.enabled ?? true
20
+ }
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Check if thenable
3
+ * (instanceof Promise doesn't respect realms)
4
+ */
5
+ export const isThenable = (value: unknown): boolean =>
6
+ typeof value === 'object' &&
7
+ value !== null &&
8
+ 'then' in value &&
9
+ typeof (value as any).then === 'function'
@@ -0,0 +1,66 @@
1
+ function findScript(src: string): HTMLScriptElement | undefined {
2
+ const scripts = Array.prototype.slice.call(
3
+ window.document.querySelectorAll('script')
4
+ )
5
+ return scripts.find((s) => s.src === src)
6
+ }
7
+
8
+ export function loadScript(
9
+ src: string,
10
+ attributes?: Record<string, string>
11
+ ): Promise<HTMLScriptElement> {
12
+ const found = findScript(src)
13
+
14
+ if (found !== undefined) {
15
+ const status = found?.getAttribute('status')
16
+
17
+ if (status === 'loaded') {
18
+ return Promise.resolve(found)
19
+ }
20
+
21
+ if (status === 'loading') {
22
+ return new Promise((resolve, reject) => {
23
+ found.addEventListener('load', () => resolve(found))
24
+ found.addEventListener('error', (err) => reject(err))
25
+ })
26
+ }
27
+ }
28
+
29
+ return new Promise((resolve, reject) => {
30
+ const script = window.document.createElement('script')
31
+
32
+ script.type = 'text/javascript'
33
+ script.src = src
34
+ script.async = true
35
+
36
+ script.setAttribute('status', 'loading')
37
+ for (const [k, v] of Object.entries(attributes ?? {})) {
38
+ script.setAttribute(k, v)
39
+ }
40
+
41
+ script.onload = (): void => {
42
+ script.onerror = script.onload = null
43
+ script.setAttribute('status', 'loaded')
44
+ resolve(script)
45
+ }
46
+
47
+ script.onerror = (): void => {
48
+ script.onerror = script.onload = null
49
+ script.setAttribute('status', 'error')
50
+ reject(new Error(`Failed to load ${src}`))
51
+ }
52
+
53
+ const tag = window.document.getElementsByTagName('script')[0]
54
+ tag.parentElement?.insertBefore(script, tag)
55
+ })
56
+ }
57
+
58
+ export function unloadScript(src: string): Promise<void> {
59
+ const found = findScript(src)
60
+
61
+ if (found !== undefined) {
62
+ found.remove()
63
+ }
64
+
65
+ return Promise.resolve()
66
+ }
@@ -0,0 +1,46 @@
1
+ import { JSONObject, Options } from '../core/events/interfaces'
2
+ import { LegacySettings } from '../browser'
3
+
4
+ /**
5
+ * Merge legacy settings and initialized Integration option overrides.
6
+ *
7
+ * This will merge any options that were passed from initialization into
8
+ * overrides for settings that are returned by the Hightouch CDN.
9
+ *
10
+ * i.e. this allows for passing options directly into destinations from
11
+ * the Analytics constructor.
12
+ */
13
+ export function mergedOptions(
14
+ settings: LegacySettings,
15
+ options: Options
16
+ ): Record<string, JSONObject> {
17
+ const optionOverrides = Object.entries(options.integrations ?? {}).reduce(
18
+ (overrides, [integration, options]) => {
19
+ if (typeof options === 'object') {
20
+ return {
21
+ ...overrides,
22
+ [integration]: options,
23
+ }
24
+ }
25
+
26
+ return {
27
+ ...overrides,
28
+ [integration]: {},
29
+ }
30
+ },
31
+ {} as Record<string, JSONObject>
32
+ )
33
+
34
+ return Object.entries(settings.integrations).reduce(
35
+ (integrationSettings, [integration, settings]) => {
36
+ return {
37
+ ...integrationSettings,
38
+ [integration]: {
39
+ ...settings,
40
+ ...optionOverrides[integration],
41
+ },
42
+ }
43
+ },
44
+ {} as Record<string, JSONObject>
45
+ )
46
+ }
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Register event listener on document that fires when:
3
+ * * tab change or tab close (in mobile or desktop)
4
+ * * click back / forward button
5
+ * * click any link or perform any other navigation action
6
+ * * soft refresh / hard refresh
7
+ *
8
+ * adapted from https://stackoverflow.com/questions/3239834/window-onbeforeunload-not-working-on-the-ipad/52864508#52864508,
9
+ */
10
+ export const onPageChange = (cb: (unloaded: boolean) => void) => {
11
+ let unloaded = false // prevents double firing if both are supported
12
+
13
+ window.addEventListener('pagehide', () => {
14
+ if (unloaded) return
15
+ unloaded = true
16
+ cb(unloaded)
17
+ })
18
+
19
+ // using document instead of window because of bug affecting browsers before safari 14 (detail in footnotes https://caniuse.com/?search=visibilitychange)
20
+ document.addEventListener('visibilitychange', () => {
21
+ if (document.visibilityState == 'hidden') {
22
+ if (unloaded) return
23
+ unloaded = true
24
+ } else {
25
+ unloaded = false
26
+ }
27
+ cb(unloaded)
28
+ })
29
+ }
@@ -0,0 +1,12 @@
1
+ export const pWhile = async <T>(
2
+ condition: (value: T | undefined) => boolean,
3
+ action: () => T | PromiseLike<T>
4
+ ): Promise<void> => {
5
+ const loop = async (actionResult: T | undefined): Promise<void> => {
6
+ if (condition(actionResult)) {
7
+ return loop(await action())
8
+ }
9
+ }
10
+
11
+ return loop(undefined)
12
+ }
@@ -0,0 +1,56 @@
1
+ import { getGlobalAnalytics } from './global-analytics-helper'
2
+
3
+ const analyticsScriptRegex =
4
+ /(https:\/\/.*)\/analytics\.js\/v1\/(?:.*?)\/(?:platform|analytics.*)?/
5
+ const getCDNUrlFromScriptTag = (): string | undefined => {
6
+ let cdn: string | undefined
7
+ const scripts = Array.prototype.slice.call(
8
+ document.querySelectorAll('script')
9
+ )
10
+ scripts.forEach((s) => {
11
+ const src = s.getAttribute('src') ?? ''
12
+ const result = analyticsScriptRegex.exec(src)
13
+
14
+ if (result && result[1]) {
15
+ cdn = result[1]
16
+ }
17
+ })
18
+ return cdn
19
+ }
20
+
21
+ let _globalCDN: string | undefined // set globalCDN as in-memory singleton
22
+ const getGlobalCDNUrl = (): string | undefined => {
23
+ const result = _globalCDN ?? getGlobalAnalytics()?._cdn
24
+ return result
25
+ }
26
+
27
+ export const setGlobalCDNUrl = (cdn: string) => {
28
+ const globalAnalytics = getGlobalAnalytics()
29
+ if (globalAnalytics) {
30
+ globalAnalytics._cdn = cdn
31
+ }
32
+ _globalCDN = cdn
33
+ }
34
+
35
+ export const getCDN = (): string => {
36
+ const globalCdnUrl = getGlobalCDNUrl()
37
+
38
+ if (globalCdnUrl) return globalCdnUrl
39
+
40
+ const cdnFromScriptTag = getCDNUrlFromScriptTag()
41
+
42
+ if (cdnFromScriptTag) {
43
+ return cdnFromScriptTag
44
+ } else {
45
+ // it's possible that the CDN is not found in the page because:
46
+ // - the script is loaded through a proxy
47
+ // - the script is removed after execution
48
+ // in this case, we fall back to the default Hightouch CDN
49
+ return `https://cdn.hightouch-events.com`
50
+ }
51
+ }
52
+
53
+ export const getNextIntegrationsURL = () => {
54
+ const cdn = getCDN()
55
+ return `${cdn}/next-integrations`
56
+ }
@@ -0,0 +1,28 @@
1
+ export function pick<T extends Record<string, any>, K extends keyof T>(
2
+ object: T,
3
+ keys: readonly K[]
4
+ ): Pick<T, K>
5
+
6
+ export function pick<T extends Record<string, any>>(
7
+ object: T,
8
+ keys: string[]
9
+ ): Partial<T>
10
+
11
+ /**
12
+ * @example
13
+ * pick({ 'a': 1, 'b': '2', 'c': 3 }, ['a', 'c'])
14
+ * => { 'a': 1, 'c': 3 }
15
+ */
16
+ export function pick<T extends Record<string, any>, K extends keyof T>(
17
+ object: T,
18
+ keys: string[] | K[] | readonly K[]
19
+ ) {
20
+ return Object.assign(
21
+ {},
22
+ ...keys.map((key) => {
23
+ if (object && Object.prototype.hasOwnProperty.call(object, key)) {
24
+ return { [key]: object[key] }
25
+ }
26
+ })
27
+ )
28
+ }
@@ -0,0 +1,23 @@
1
+ import { backoff } from '../backoff'
2
+
3
+ describe('backoff', () => {
4
+ it('increases with the number of attempts', () => {
5
+ expect(backoff({ attempt: 1 })).toBeGreaterThan(1000)
6
+ expect(backoff({ attempt: 2 })).toBeGreaterThan(2000)
7
+ expect(backoff({ attempt: 3 })).toBeGreaterThan(3000)
8
+ expect(backoff({ attempt: 4 })).toBeGreaterThan(4000)
9
+ })
10
+
11
+ it('accepts a max timeout', () => {
12
+ expect(backoff({ attempt: 1, maxTimeout: 3000 })).toBeGreaterThan(1000)
13
+ expect(backoff({ attempt: 3, maxTimeout: 3000 })).toBeLessThanOrEqual(3000)
14
+ expect(backoff({ attempt: 4, maxTimeout: 3000 })).toBeLessThanOrEqual(3000)
15
+ })
16
+
17
+ it('accepts a growth factor', () => {
18
+ const f2 = backoff({ attempt: 2, factor: 2 })
19
+ const f3 = backoff({ attempt: 2, factor: 3 })
20
+
21
+ expect(f3).toBeGreaterThan(f2)
22
+ })
23
+ })
@@ -0,0 +1,158 @@
1
+ import { PriorityQueue } from '..'
2
+
3
+ type Item = {
4
+ id: string
5
+ }
6
+
7
+ describe('RetryQueue', () => {
8
+ it('accepts new work', () => {
9
+ const queue = new PriorityQueue<Item>(10, [])
10
+ queue.push({ id: 'abc' }, { id: 'cde' })
11
+ expect(queue.length).toBe(2)
12
+ })
13
+
14
+ it('pops items off the queue', () => {
15
+ const queue = new PriorityQueue<Item>(10, [])
16
+ queue.push({ id: 'abc' }, { id: 'cde' })
17
+
18
+ expect(queue.pop()).toEqual({ id: 'abc' })
19
+ expect(queue.length).toBe(1)
20
+
21
+ expect(queue.pop()).toEqual({ id: 'cde' })
22
+ expect(queue.length).toBe(0)
23
+ })
24
+
25
+ it('deprioritizes repeated items', () => {
26
+ const queue = new PriorityQueue<Item>(10, [])
27
+ queue.push({ id: 'abc' })
28
+ queue.push({ id: 'abc' })
29
+
30
+ queue.push({ id: 'cde' })
31
+
32
+ // deprioritizes 'abc' because it was seen twice
33
+ expect(queue.pop()).toEqual({ id: 'cde' })
34
+ })
35
+
36
+ it('deprioritizes repeated items even though they have been popped before', () => {
37
+ const queue = new PriorityQueue<Item>(10, [])
38
+ queue.push({ id: 'abc' })
39
+ queue.pop()
40
+
41
+ queue.push({ id: 'abc' })
42
+ queue.push({ id: 'cde' })
43
+
44
+ // a queue does not forget
45
+ expect(queue.pop()).toEqual({ id: 'cde' })
46
+ })
47
+
48
+ it('stops accepting an item after attempts have been exausted', () => {
49
+ const queue = new PriorityQueue<Item>(3, [])
50
+ queue.push({ id: 'abc' })
51
+ expect(queue.length).toBe(1)
52
+ queue.pop()
53
+
54
+ queue.push({ id: 'abc' })
55
+ expect(queue.length).toBe(1)
56
+ queue.pop()
57
+
58
+ queue.push({ id: 'abc' })
59
+ expect(queue.length).toBe(1)
60
+ queue.pop()
61
+
62
+ queue.push({ id: 'abc' })
63
+ // does not accept it anymore
64
+ expect(queue.length).toBe(0)
65
+ })
66
+ })
67
+
68
+ describe('backoffs', () => {
69
+ afterEach(() => {
70
+ jest.clearAllTimers()
71
+ })
72
+
73
+ it('accepts new work', () => {
74
+ const queue = new PriorityQueue<Item>(10, [])
75
+
76
+ queue.pushWithBackoff({ id: 'abc' })
77
+ queue.pushWithBackoff({ id: 'cde' })
78
+
79
+ expect(queue.length).toBe(2)
80
+ expect(queue.todo).toBe(2)
81
+ })
82
+
83
+ it('ignores when item has not been worked on', () => {
84
+ const queue = new PriorityQueue<Item>(10, [])
85
+
86
+ expect(queue.pushWithBackoff({ id: 'abc' })).toBe(true)
87
+ expect(queue.pushWithBackoff({ id: 'abc' })).toBe(false)
88
+ expect(queue.length).toBe(1)
89
+ expect(queue.todo).toBe(1)
90
+ })
91
+
92
+ it('schedules as future work when item returns to the queue', () => {
93
+ const queue = new PriorityQueue<Item>(10, [])
94
+
95
+ queue.pushWithBackoff({ id: 'abc' })
96
+ queue.pop()
97
+
98
+ // accepted work
99
+ expect(queue.pushWithBackoff({ id: 'abc' })).toBe(true)
100
+
101
+ // not in the main queue yet
102
+ expect(queue.length).toBe(0)
103
+
104
+ // present in future work
105
+ expect(queue.todo).toBe(1)
106
+ expect(queue.includes({ id: 'abc' })).toBe(true)
107
+ })
108
+
109
+ it('schedules as future work for later', () => {
110
+ jest.useFakeTimers()
111
+ const spy = jest.spyOn(global, 'setTimeout')
112
+
113
+ const queue = new PriorityQueue<Item>(10, [])
114
+
115
+ queue.pushWithBackoff({ id: 'abc' })
116
+ expect(spy).not.toHaveBeenCalled()
117
+
118
+ queue.pop()
119
+
120
+ queue.pushWithBackoff({ id: 'abc' })
121
+ expect(spy).toHaveBeenCalled()
122
+
123
+ const delay = spy.mock.calls[0][1]
124
+ expect(delay).toBeGreaterThan(1000)
125
+ })
126
+
127
+ it('increases the delay as work gets requeued', () => {
128
+ jest.useFakeTimers()
129
+ const spy = jest.spyOn(global, 'setTimeout')
130
+
131
+ const queue = new PriorityQueue<Item>(10, [])
132
+
133
+ queue.pushWithBackoff({ id: 'abc' })
134
+ jest.advanceTimersToNextTimer()
135
+ queue.pop()
136
+
137
+ queue.pushWithBackoff({ id: 'abc' })
138
+ jest.advanceTimersToNextTimer()
139
+ queue.pop()
140
+
141
+ queue.pushWithBackoff({ id: 'abc' })
142
+ jest.advanceTimersToNextTimer()
143
+ queue.pop()
144
+
145
+ queue.pushWithBackoff({ id: 'abc' })
146
+ jest.advanceTimersToNextTimer()
147
+ queue.pop()
148
+
149
+ const firstDelay = spy.mock.calls[0][1]
150
+ expect(firstDelay).toBeGreaterThan(1000)
151
+
152
+ const secondDelay = spy.mock.calls[1][1]
153
+ expect(secondDelay).toBeGreaterThan(2000)
154
+
155
+ const thirdDelay = spy.mock.calls[2][1]
156
+ expect(thirdDelay).toBeGreaterThan(3000)
157
+ })
158
+ })