From 25781aff31ed87d07d9f556240722d4f7d74523c Mon Sep 17 00:00:00 2001 From: Seth Silesky <5115498+silesky@users.noreply.github.com> Date: Wed, 9 Jul 2025 16:35:39 -0500 Subject: [PATCH 1/5] update tests --- .../src/tests/signals-vanilla/basic.test.ts | 8 +- .../network-signals-allow-list.test.ts | 4 +- .../signals-vanilla/runtime-constants.test.ts | 44 --- packages/signals/signals-runtime/.eslintrc.js | 7 - .../signals/signals-runtime/.lintstagedrc.js | 1 - packages/signals/signals-runtime/CHANGELOG.md | 56 --- packages/signals/signals-runtime/LICENSE | 324 ------------------ packages/signals/signals-runtime/README.md | 69 ---- .../signals-runtime/api-extractor.base.json | 33 -- .../signals-runtime/api-extractor.mobile.json | 8 - .../signals-runtime/api-extractor.web.json | 8 - .../signals-runtime/build-editor-types.js | 48 --- .../build-signals-runtime-global.js | 122 ------- .../bundle-build-tests/runtime-env.test.ts | 73 ---- .../signals/signals-runtime/jest.config.js | 6 - .../signals/signals-runtime/jest.setup.js | 9 - packages/signals/signals-runtime/package.json | 56 --- .../scripts/assert-generated.sh | 17 - .../src/__tests__/signals-runtime.test.ts | 118 ------- packages/signals/signals-runtime/src/index.ts | 17 - .../src/mobile/get-runtime-code.generated.ts | 7 - .../src/mobile/index.mobile-editor.ts | 11 - .../src/mobile/index.signals-runtime.ts | 13 - .../src/mobile/mobile-constants.ts | 40 --- .../src/mobile/mobile-signals-runtime.ts | 33 -- .../src/mobile/mobile-signals-types.ts | 90 ----- .../src/shared/shared-types.ts | 25 -- .../src/shared/signals-runtime.ts | 52 --- .../mocks/mock-signal-types-web.ts | 87 ----- .../src/web/get-runtime-code.generated.ts | 7 - .../src/web/index.signals-runtime.ts | 11 - .../src/web/index.web-editor.ts | 11 - .../signals-runtime/src/web/web-constants.ts | 22 -- .../src/web/web-signals-runtime.ts | 4 - .../src/web/web-signals-types.ts | 186 ---------- .../signals-runtime/tsconfig.build.json | 10 - .../signals/signals-runtime/tsconfig.json | 12 - packages/signals/signals/package.json | 2 +- .../__tests__/analytics-service.test.ts | 9 + .../network-signals-filter.ts | 5 - .../signals-ingest/__tests__/client.test.ts | 21 +- .../signals-ingest/__tests__/redact.test.ts | 43 +-- .../core/middleware/signals-ingest/redact.ts | 2 +- .../signals-ingest/signals-ingest-client.ts | 2 +- .../signals/src/core/processor/sandbox.ts | 16 +- .../dom-gen/__tests__/change-gen.test.ts | 16 + .../dom-gen/__tests__/navigation-gen.test.ts | 24 +- .../dom-gen/navigation-gen.ts | 7 +- .../__tests__/network-generator.test.ts | 38 +- .../signal-generators/network-gen/index.ts | 8 +- .../__tests__/create-network-signal.test.ts | 75 ++-- .../signals/signals/src/types/factories.ts | 35 +- .../signals/src/types/process-signal.ts | 8 +- yarn.lock | 291 +--------------- 54 files changed, 170 insertions(+), 2081 deletions(-) delete mode 100644 packages/signals/signals-integration-tests/src/tests/signals-vanilla/runtime-constants.test.ts delete mode 100644 packages/signals/signals-runtime/.eslintrc.js delete mode 100644 packages/signals/signals-runtime/.lintstagedrc.js delete mode 100644 packages/signals/signals-runtime/CHANGELOG.md delete mode 100644 packages/signals/signals-runtime/LICENSE delete mode 100644 packages/signals/signals-runtime/README.md delete mode 100644 packages/signals/signals-runtime/api-extractor.base.json delete mode 100644 packages/signals/signals-runtime/api-extractor.mobile.json delete mode 100644 packages/signals/signals-runtime/api-extractor.web.json delete mode 100644 packages/signals/signals-runtime/build-editor-types.js delete mode 100644 packages/signals/signals-runtime/build-signals-runtime-global.js delete mode 100644 packages/signals/signals-runtime/bundle-build-tests/runtime-env.test.ts delete mode 100644 packages/signals/signals-runtime/jest.config.js delete mode 100644 packages/signals/signals-runtime/jest.setup.js delete mode 100644 packages/signals/signals-runtime/package.json delete mode 100644 packages/signals/signals-runtime/scripts/assert-generated.sh delete mode 100644 packages/signals/signals-runtime/src/__tests__/signals-runtime.test.ts delete mode 100644 packages/signals/signals-runtime/src/index.ts delete mode 100644 packages/signals/signals-runtime/src/mobile/get-runtime-code.generated.ts delete mode 100644 packages/signals/signals-runtime/src/mobile/index.mobile-editor.ts delete mode 100644 packages/signals/signals-runtime/src/mobile/index.signals-runtime.ts delete mode 100644 packages/signals/signals-runtime/src/mobile/mobile-constants.ts delete mode 100644 packages/signals/signals-runtime/src/mobile/mobile-signals-runtime.ts delete mode 100644 packages/signals/signals-runtime/src/mobile/mobile-signals-types.ts delete mode 100644 packages/signals/signals-runtime/src/shared/shared-types.ts delete mode 100644 packages/signals/signals-runtime/src/shared/signals-runtime.ts delete mode 100644 packages/signals/signals-runtime/src/test-helpers/mocks/mock-signal-types-web.ts delete mode 100644 packages/signals/signals-runtime/src/web/get-runtime-code.generated.ts delete mode 100644 packages/signals/signals-runtime/src/web/index.signals-runtime.ts delete mode 100644 packages/signals/signals-runtime/src/web/index.web-editor.ts delete mode 100644 packages/signals/signals-runtime/src/web/web-constants.ts delete mode 100644 packages/signals/signals-runtime/src/web/web-signals-runtime.ts delete mode 100644 packages/signals/signals-runtime/src/web/web-signals-types.ts delete mode 100644 packages/signals/signals-runtime/tsconfig.build.json delete mode 100644 packages/signals/signals-runtime/tsconfig.json diff --git a/packages/signals/signals-integration-tests/src/tests/signals-vanilla/basic.test.ts b/packages/signals/signals-integration-tests/src/tests/signals-vanilla/basic.test.ts index ff618682e..4317d1f33 100644 --- a/packages/signals/signals-integration-tests/src/tests/signals-vanilla/basic.test.ts +++ b/packages/signals/signals-integration-tests/src/tests/signals-vanilla/basic.test.ts @@ -29,13 +29,13 @@ test('network signals fetch', async () => { (el) => el.properties!.data.action === 'request' ) expect(requests).toHaveLength(1) - expect(requests[0].properties!.data.data).toEqual({ foo: 'bar' }) + expect(requests[0].properties!.data.body).toEqual({ foo: 'bar' }) const responses = networkEvents.filter( (el) => el.properties!.data.action === 'response' ) expect(responses).toHaveLength(1) - expect(responses[0].properties!.data.data).toEqual({ someResponse: 'yep' }) + expect(responses[0].properties!.data.body).toEqual({ someResponse: 'yep' }) }) test('network signals xhr', async () => { @@ -51,13 +51,13 @@ test('network signals xhr', async () => { (el) => el.properties!.data.action === 'request' ) expect(requests).toHaveLength(1) - expect(requests[0].properties!.data.data).toEqual({ foo: 'bar' }) + expect(requests[0].properties!.data.body).toEqual({ foo: 'bar' }) const responses = networkEvents.filter( (el) => el.properties!.data.action === 'response' ) expect(responses).toHaveLength(1) - expect(responses[0].properties!.data.data).toEqual({ someResponse: 'yep' }) + expect(responses[0].properties!.data.body).toEqual({ someResponse: 'yep' }) expect(responses[0].properties!.data.page).toEqual(commonSignalData.page) }) diff --git a/packages/signals/signals-integration-tests/src/tests/signals-vanilla/network-signals-allow-list.test.ts b/packages/signals/signals-integration-tests/src/tests/signals-vanilla/network-signals-allow-list.test.ts index 097813b6e..6ce8686a3 100644 --- a/packages/signals/signals-integration-tests/src/tests/signals-vanilla/network-signals-allow-list.test.ts +++ b/packages/signals/signals-integration-tests/src/tests/signals-vanilla/network-signals-allow-list.test.ts @@ -25,10 +25,10 @@ test('network signals allow and disallow list', async ({ page }) => { ) expect(allowedRequestsAndResponses).toHaveLength(2) const [request, response] = allowedRequestsAndResponses - expect(request.properties!.data.data).toEqual({ + expect(request.properties!.data.body).toEqual({ foo: 'bar', }) - expect(response.properties!.data.data).toEqual({ + expect(response.properties!.data.body).toEqual({ someResponse: 'yep', }) diff --git a/packages/signals/signals-integration-tests/src/tests/signals-vanilla/runtime-constants.test.ts b/packages/signals/signals-integration-tests/src/tests/signals-vanilla/runtime-constants.test.ts deleted file mode 100644 index 644d18366..000000000 --- a/packages/signals/signals-integration-tests/src/tests/signals-vanilla/runtime-constants.test.ts +++ /dev/null @@ -1,44 +0,0 @@ -import { test, expect } from '@playwright/test' -import { IndexPage } from './index-page' - -const basicEdgeFn = ` - globalThis.processSignal = (signal) => { - // test that constants are properly injected - if (typeof EventType !== 'object') { - throw new Error('EventType is missing?') - } - if (typeof SignalType !== 'object') { - throw new Error('SignalType is missing?') - } - if (typeof NavigationAction !== 'object') { - throw new Error('NavigationAction is missing?') - } - - if (signal.type === SignalType.Interaction) { - const eventName = signal.data.eventType + ' ' + '[' + signal.type + ']' - analytics.track(eventName, signal.data) - } - }` - -let indexPage: IndexPage - -test.beforeEach(async ({ page }) => { - indexPage = await new IndexPage().loadAndWait(page, basicEdgeFn) -}) - -test('constants should be accessible in the runtime', async () => { - /** - * Make a button click, see ifdom.window.NavigationAction.URLChange it: - * - creates an interaction signal that sends to the signals endpoint - * - creates an analytics event that sends to the tracking endpoint - */ - await Promise.all([ - indexPage.clickButton(), - indexPage.waitForTrackingApiFlush(), - ]) - - const analyticsReqJSON = indexPage.trackingAPI.lastEvent() - expect(analyticsReqJSON).toMatchObject({ - event: 'click [interaction]', - }) -}) diff --git a/packages/signals/signals-runtime/.eslintrc.js b/packages/signals/signals-runtime/.eslintrc.js deleted file mode 100644 index eedf2f3c3..000000000 --- a/packages/signals/signals-runtime/.eslintrc.js +++ /dev/null @@ -1,7 +0,0 @@ -/** @type { import('eslint').Linter.Config } */ -module.exports = { - extends: ['../../../.eslintrc'], - env: { - browser: true, - }, -} diff --git a/packages/signals/signals-runtime/.lintstagedrc.js b/packages/signals/signals-runtime/.lintstagedrc.js deleted file mode 100644 index bc1f1c780..000000000 --- a/packages/signals/signals-runtime/.lintstagedrc.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = require("@internal/config").lintStagedConfig diff --git a/packages/signals/signals-runtime/CHANGELOG.md b/packages/signals/signals-runtime/CHANGELOG.md deleted file mode 100644 index 53557c8e6..000000000 --- a/packages/signals/signals-runtime/CHANGELOG.md +++ /dev/null @@ -1,56 +0,0 @@ -# @segment/analytics-signals-runtime - -## 1.5.1 - -### Patch Changes - -- [#1274](https://github.com/segmentio/analytics-next/pull/1274) [`a00fa28d`](https://github.com/segmentio/analytics-next/commit/a00fa28d76af890f1e2adb69ea0b0860beafca15) Thanks [@silesky](https://github.com/silesky)! - Add a changedProperties array to navigation signals - -## 1.5.0 - -### Minor Changes - -- [#1263](https://github.com/segmentio/analytics-next/pull/1263) [`6753b4b4`](https://github.com/segmentio/analytics-next/commit/6753b4b40d5378734b51369510e707e813a0ad5e) Thanks [@silesky](https://github.com/silesky)! - Add anonymousID and timestamp to signals - -## 1.4.0 - -### Minor Changes - -- [#1250](https://github.com/segmentio/analytics-next/pull/1250) [`d5829da8`](https://github.com/segmentio/analytics-next/commit/d5829da8ce6a1664d9be2e00960791d929ee73bc) Thanks [@silesky](https://github.com/silesky)! - Transpile to ES5 - -## 1.3.0 - -### Minor Changes - -- [#1238](https://github.com/segmentio/analytics-next/pull/1238) [`0596bc45`](https://github.com/segmentio/analytics-next/commit/0596bc455b9ecf8ed179f1be5decb0a4b89bb9a5) Thanks [@silesky](https://github.com/silesky)! - Add page data to web signals - -## 1.2.1 - -### Patch Changes - -- [#1230](https://github.com/segmentio/analytics-next/pull/1230) [`2fc749a1`](https://github.com/segmentio/analytics-next/commit/2fc749a17b14b2667df76ecce685aefb6656eaae) Thanks [@silesky](https://github.com/silesky)! - Update license key - -## 1.2.0 - -### Minor Changes - -- [#1202](https://github.com/segmentio/analytics-next/pull/1202) [`00a736f3`](https://github.com/segmentio/analytics-next/commit/00a736f31326328e91c9cae0b244b9db9b0791fc) Thanks [@silesky](https://github.com/silesky)! - - Add support for interaction signals for custom components and elements with contenteditable property - - Allow custom disallow list to override network signals, even if same domain. - -## 1.1.1 - -### Patch Changes - -- [#1197](https://github.com/segmentio/analytics-next/pull/1197) [`342868cb`](https://github.com/segmentio/analytics-next/commit/342868cb9db7da37d8851dadca4b1b1dc0ecd923) Thanks [@silesky](https://github.com/silesky)! - Update signals license - -## 1.1.0 - -### Minor Changes - -- [#1181](https://github.com/segmentio/analytics-next/pull/1181) [`6fff4114`](https://github.com/segmentio/analytics-next/commit/6fff4114fb2cc9267362d8a3812ad96ec85a1dac) Thanks [@silesky](https://github.com/silesky)! - Add HTTPMethods. Do not gate requests based on content-type. - -## 1.0.0 - -### Major Changes - -- [#1168](https://github.com/segmentio/analytics-next/pull/1168) [`ba2f2b16`](https://github.com/segmentio/analytics-next/commit/ba2f2b165bf1b997a9ce79d410690d27d50378fd) Thanks [@silesky](https://github.com/silesky)! - Release analytics-signals-runtime diff --git a/packages/signals/signals-runtime/LICENSE b/packages/signals/signals-runtime/LICENSE deleted file mode 100644 index 73b54b76c..000000000 --- a/packages/signals/signals-runtime/LICENSE +++ /dev/null @@ -1,324 +0,0 @@ -Twilio Software Development Kit License Agreement 2.0 - -Notice to user: THIS IS A TWILIO SOFTWARE DEVELOPMENT KIT LICENSE AGREEMENT 2.0 -BETWEEN YOU AND TWILIO FOR ACCESS TO AND USE OF TWILIO'S SOFTWARE DEVELOPMENT -KIT. BY USING THIS SOFTWARE DEVELOPMENT KIT, YOU ACCEPT ALL THE TERMS AND -CONDITIONS OF THIS TWILIO SOFTWARE DEVELOPMENT KIT LICENSE AGREEMENT 2.0. - -As a courtesy, below is a quick summary of how this Twilio Software Development -Kit License Agreement 2.0 applies when you download, use, or otherwise access -this Twilio Software Development Kit. The full version can be found by scrolling -down and is the only one that is legally controlling and binding. - -Summary - -When you download, use, or otherwise access this software development kit: - -* Twilio grants you a limited license to use this software development kit only - for the purposes of developing your own applications and software and - distributing those applications and software in connection with your use of - Twilio's products and services as a Twilio customer. - -* You agree not to use this software development kit to create a competing - product or service to this software development kit. - -* You agree that Twilio may make changes or updates to this software development - kit (including discontinuing support for and/or the availability of this - software development kit) at any time for any reason. - -* You agree that you will not use this software development kit in any way that - interferes with, disrupts, damages or otherwise affects anyone's servers, - networks, or services (including Twilio's). - -* You agree that any feedback you provide to Twilio regarding this software - development kit, including any suggestions for improvements, belong to Twilio - without any compensation to you and that Twilio owns all legal rights to that - feedback. - -* Except for this software development kit, any use of Twilio's products and - services is governed by a separate agreement between you and Twilio. - -Full Version - -1. Introduction - - a. This Twilio Software Development Kit License Agreement 2.0 (this - "Agreement") accompanies the Twilio Software Development Kit for the - software and related explanatory materials (including the Software and - Documentation, the "SDK") and includes any upgrades, modified versions, - updates, additions, and copies of the SDK licensed to you by Twilio. Twilio - and you may be referred to herein collectively as the "parties" or - individually as a "party." - - b. "Documentation" means Twilio's user manuals, handbooks, installation - guides, and any explanatory materials relating to or accompanying the SDK - provided by Twilio to you either electronically or in hard copy form. - - c. "Intellectual Property Rights" means any and all rights under patent law, - copyright law, trade secret law, trademark law, and any and all other - proprietary rights. - - d. "Software" means the object and source code, and/or other original works of - authorship in the SDK provided by Twilio to you, including all associated - example code, other tools and any upgrades, modified versions, updates, - additions, and copies provided to you pursuant to this Agreement. - - e. "Twilio" means Twilio Inc., organized under the laws of the State of - Delaware, USA, and operating under the laws of the USA with its principal - place of business at 101 Spear Street, 5th Floor, San Francisco, CA 94105. - -2. Accepting this Agreement - - a. In order to use the SDK, you must first agree to this Agreement. You may - not use the SDK if you do not accept this Agreement. By using the SDK, you - hereby agree to the terms of this Agreement. You may not use the SDK and - may not accept this Agreement if you are a person barred from receiving the - SDK under the laws of the United States or other countries, including the - country in which you are a resident or from which you use the SDK. If you - are agreeing to be bound by this Agreement on behalf of your employer or - other entity, you represent and warrant that you have full legal authority - to bind your employer or such entity to this Agreement. If you do not have - the requisite authority, you may not accept this Agreement or use the SDK - on behalf of your employer or other entity. You must use the SDK in - conjunction with Twilio's products and services ("Twilio Services"), and - your use of the Twilio Services will solely be governed by the Twilio Terms - of Service available at https://www.twilio.com/legal/tos or a separate - written agreement entered into between you and Twilio (each, a "Services - Agreement"). This Agreement will, in no way, modify or affect the terms of - the applicable Services Agreement. - -3. SDK License from Twilio - - a. Subject to the terms and conditions of this Agreement, Twilio grants you a - non-exclusive, non-sublicensable, non-assignable, non-transferable, - worldwide, royalty-free, access to and license to use the SDK solely (i) to - copy, display, perform, modify, and create derivative works from the SDK - only for the purpose of internal development of your software products - (each, an "Application") solely for an Application's use in conjunction - with the Twilio Services; and (ii) distribute the Software as part of an - Application, provided that you have a Services Agreement with Twilio for - the use of such Twilio Services. The license granted in Section 3(a)(ii) - will survive the termination of this Agreement, except to the extent you - are in material breach of any of the obligations hereunder. - - b. You are responsible and liable for all use of the SDK, directly or - indirectly, whether such access or use is permitted by or in violation of - this Agreement. Twilio has no liability to you or any third party arising - or resulting from your use of the SDK. - - c. Use, reproduction, and distribution of software dependencies and components - of the SDK licensed under an open source software license are governed - solely by the terms of that open source software license and not this - Agreement. You understand and acknowledge that such open source software is - not licensed to you pursuant to the provisions of this Agreement and that - this Agreement may not be construed to grant any such right and/or - license. If you do not agree to abide by the applicable terms for such - components of the SDK licensed under an open source software license, then - you should not use the SDK. - - d. You will not remove, obscure, or alter any proprietary rights notices - (including copyright and trademark notices) that may be affixed to or - contained within the SDK. - -4. Use of the SDK by You - - a. You may not use the SDK to develop a competing product or service to the - SDK or for any purposes not expressly permitted by this Agreement - including, but not limited to, using the SDK in any manner or for any - purpose that infringes, misappropriates, or otherwise violates any - Intellectual Property Right or other right of any person, or that violates - any applicable law or regulation (including any laws regarding the export - of data or software to and from the United States or other relevant - countries). - - b. You acknowledge and agree that Twilio has no obligation to provide - updates, upgrades, or any other modifications to the SDK. In addition, you - acknowledge and agree that Twilio has no obligation to support or maintain - the SDK. - - c. You agree that the form and nature of the SDK that Twilio provides may - change without prior notice to you and that future versions of the SDK may - be incompatible with Applications developed on previous versions of the - SDK. You agree that Twilio may stop (permanently or temporarily) providing - the SDK (or any features within the SDK) to you or to users generally at - Twilio's sole discretion, without prior notice to you. - - d. You agree that you will not engage in any activity with the SDK, - including the development or distribution of an Application, that - interferes with, disrupts, damages, or accesses in an unauthorized manner - the servers, networks, or other properties or services of any third party - including, but not limited to, Twilio or any telecommunications provider. - - e. Nothing in this Agreement gives you a right to use any of Twilio's trade - names, trademarks, service marks, logos, domain names, or other - distinctive brand features. - - f. You agree that you are solely responsible for (and that Twilio has no - responsibility to you or to any third party for) any breach of your - obligations under this Agreement, any applicable third party contract, or - any applicable law or regulation, and for the consequences (including any - loss or damage which Twilio or any third party may suffer) of any such - breach. - -5. Intellectual Property Ownership and Feedback - - a. You agree that Twilio or third parties own all legal right, title, and - interest in and to the SDK, including any Intellectual Property Rights - that subsist in the SDK. Twilio reserves all rights not expressly granted - to you in this Agreement. Except for the limited rights and licenses - expressly granted under this Agreement, nothing in this Agreement grants, - by implication, waiver, estoppel, or otherwise, to your or any third - party any Intellectual Property Rights or other right, title, or interest - in or to the SDK. - - b. Twilio agrees that it obtains no right, title or interest from you (or - your licensors) under this Agreement in or to any Applications that you - develop using the SDK, including any Intellectual Property Rights that - subsist in those Applications. - - c. If you or any of your employees or contractors send or transmit any - communications, materials, code, documentation, or other original works of - authorship (including any modifications) to Twilio by any form of - electronic or written communication, including but not limited to mail, - email, telephone, source code control systems, issue tracking systems, or - otherwise, suggesting or recommending changes to the SDK, including - without limitation, new features or functionality relating thereto, or any - comments, questions, suggestions, or the like ("Feedback"), Twilio is free - to use such Feedback irrespective of any other obligation or limitation - between the parties governing such Feedback. You hereby assign to Twilio - on your behalf, and on behalf of your employees, contractors and/or - agents, all right, title, and interest in, and Twilio is free to use, - Feedback without any attribution or compensation to any party, any ideas, - know-how, concepts, techniques, or other Intellectual Property Rights - contained in the Feedback, for any purpose whatsoever. Twilio is not - required to use any Feedback. For clarity, Feedback will not include any - code, documentation, or works of authorship, including the Intellectual - Property Rights embedded therein, which are (a) unrelated to the core - functionality of the Software or (b) conceived and/or developed by you (i) - prior to the date this Agreement is accepted by you, (ii) outside the - scope of this Agreement, or (iii) independently without the use of the - SDK. - -6. Terminating this Agreement - - a. This Agreement, as may be updated from time to time, will commence on the - date it is accepted by you and continue until terminated as set out below. - - b. If you want to terminate this Agreement, you may do so by ceasing your - use of the SDK. - - c. Without prejudice to any other rights, this Agreement shall terminate - automatically without notice from Twilio if: - i. your Services Agreement for use of the Twilio Services terminates; or - ii. you have breached any provision of this Agreement; or - iii. Twilio is required to do so by law or regulation; or - iv. Twilio decides to no longer provide the SDK or certain parts of the - SDK to users in the country in which you are resident or from which - you use the service, or the provision of the SDK or certain SDK - services to you by Twilio is, in Twilio's sole discretion, no longer - commercially viable. - - d. When this Agreement terminates, all of the legal rights, obligations, and - liabilities that you and Twilio have benefited from, been subject to (or - which have accrued over time whilst this Agreement has been in force) or - which are expressed to continue indefinitely, will be unaffected by this - cessation. - -7. DISCLAIMER OF WARRANTIES - - a. YOU EXPRESSLY UNDERSTAND AND AGREE THAT YOUR USE OF THE SDK IS AT YOUR - SOLE RISK AND THAT THE SDK IS PROVIDED "AS IS" AND "AS AVAILABLE" WITHOUT - WARRANTY OF ANY KIND FROM TWILIO. - - b. YOUR USE OF THE SDK AND ANY MATERIAL DOWNLOADED OR OTHERWISE OBTAINED - THROUGH THE USE OF THE SDK IS AT YOUR OWN DISCRETION AND RISK AND YOU ARE - SOLELY RESPONSIBLE FOR ANY DAMAGE TO YOUR COMPUTER SYSTEM OR OTHER DEVICE - OR LOSS OF DATA THAT RESULTS FROM SUCH USE. - - c. TWILIO FURTHER EXPRESSLY DISCLAIMS ALL WARRANTIES AND CONDITIONS OF ANY - KIND, WHETHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO THE - IMPLIED WARRANTIES AND CONDITIONS OF MERCHANTABILITY, FITNESS FOR A - PARTICULAR PURPOSE AND NON-INFRINGEMENT. - -8. LIMITATION OF LIABILITY - - a. YOU EXPRESSLY UNDERSTAND AND AGREE THAT TWILIO, ITS SUBSIDIARIES AND - AFFILIATES, AND ITS LICENSORS WILL NOT BE LIABLE TO YOU UNDER ANY THEORY - OF LIABILITY FOR ANY DAMAGES WHATSOEVER, INCLUDING, BUT NOT LIMITED TO, - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, CONSEQUENTIAL, OR EXEMPLARY - DAMAGES THAT MAY BE INCURRED BY YOU, INCLUDING ANY LOSS OF DATA, WHETHER - OR NOT TWILIO OR ITS REPRESENTATIVES HAVE BEEN ADVISED OF OR SHOULD HAVE - BEEN AWARE OF THE POSSIBILITY OF ANY SUCH DAMAGES OR LOSSES ARISING. - -9. Indemnification - - a. To the maximum extent permitted by law, you agree to defend, indemnify - and hold harmless Twilio, its affiliates and their respective directors, - officers, employees, and agents from and against any and all claims, - actions, demands, suits, or proceedings, as well as any and all losses, - liabilities, damages, costs and expenses (including reasonable attorneys' - fees) arising out of or accruing from (a) your use of the SDK or any - resulting Application you develop on the SDK; (b) any Application you - develop using the SDK that infringes any copyright, trademark, trade - secret, trade dress, patent, or other intellectual property right of any - person or defames any person or violates their rights of publicity or - privacy; and (c) your non-compliance with the terms of this Agreement. - -10. Changes to this Agreement - - a. Twilio may make changes to this Agreement as it distributes new versions - of the SDK. When these changes are made, Twilio will make a new version - of this Agreement available on the website where the SDK is made - available. - -11. Additional Terms - - a. Except as provided in this Agreement, this Agreement supersedes all prior - and contemporaneous agreements, oral and written, in relation to the SDK. - No oral or written information or advice given by Twilio, its agents or - employees will create a warranty or in any way increase the scope of the - warranties or obligations under this Agreement. Except as permitted in - Section 10 of this Agreement, no modification to this Agreement will be - legally binding unless set forth in writing and signed by you and Twilio. - - b. You agree that Twilio's failure to enforce at any time any provision of - this Agreement or any other of your obligations does not waive Twilio's - right to do so later. And, if Twilio does expressly waive any provision - of this Agreement or any of your other obligations, that does not mean it - is waived for all time in the future. Any waiver must be in writing and - signed by you and Twilio to be legally binding. - - c. If any court of law, having the jurisdiction to decide on this matter, - rules that any provision of this Agreement is invalid, then that - provision will be removed from this Agreement without affecting the rest - of this Agreement. The remaining provisions of this Agreement will - continue to be valid and enforceable. - - d. You acknowledge and agree that each member of the group of companies of - which Twilio is the parent will be third party beneficiaries to this - Agreement and that such other companies will be entitled to directly - enforce, and rely upon, any provision of this Agreement that confers a - benefit on (or rights in favor of) them. Other than this, no other - person or company will be third party beneficiaries to this Agreement. - - e. THE SDK IS SUBJECT TO UNITED STATES EXPORT LAWS AND REGULATIONS. YOU - MUST COMPLY WITH ALL DOMESTIC AND INTERNATIONAL EXPORT LAWS AND - REGULATIONS THAT APPLY TO THE SDK. THESE LAWS INCLUDE RESTRICTIONS ON - DESTINATIONS, END USERS, AND END USE. - - f. You will not assign or otherwise transfer this Agreement, in whole or in - part, without Twilio's prior written consent. Any attempt by you to - assign, delegate, or transfer this Agreement will be void. Twilio may - assign this Agreement, in whole or in part, without consent. Subject to - this Section 13(f), this Agreement will be binding on both you and - Twilio and both parties' successors and assigns. - - g. This Agreement will be governed by and interpreted according to the laws - of the State of California without regard to conflicts of laws and - principles that would cause laws of another jurisdiction to apply. This - Agreement will not be governed by the United Nations Convention on - Contracts for the International Sale of Goods. Any legal suit, action or - proceeding arising out of or related to this Agreement or the SDK will be - instituted in either the state or federal courts of San Francisco, - California, and the parties each consent to the personal jurisdiction of - these courts. diff --git a/packages/signals/signals-runtime/README.md b/packages/signals/signals-runtime/README.md deleted file mode 100644 index e92dc1138..000000000 --- a/packages/signals/signals-runtime/README.md +++ /dev/null @@ -1,69 +0,0 @@ -# @segment/analytics-signals-runtime -Encapsulates Signals runtime functionality, in order to share logic between the signals plugins for browser and mobile. - -### Installation -```bash -# npm -npm install @segment/analytics-signals-runtime -# yarn -yarn add @segment/analytics-signals-runtime -# pnpm -pnpm install @segment/analytics-signals-runtime -``` - -### Usage - -### Importing the signals runtime as a module (e.g. `signals.find()`) - -```ts -import { WebSignalsRuntime, Signal } from '@segment/analytics-signals-runtime' -// MobileSignalsRuntime -// WebRuntimeConstants, -// MobileRuntimeConstants, - -const mockSignalBuffer: Signal[] = [{ - type: "network", - data: { - action: "response", - url: "https://segment-integrations.github.io/segment-shop-auto/cart", - data: { foo: "bar" }, - ok: true, - status: 201, - contentType: "application/json", - page: { - path: "/segment-shop-auto/", - referrer: "", - title: "Segment Shop - Home Collection - Timecraft", - search: "", - url: "https://segment-integrations.github.io/segment-shop-auto/#/home-collection/Timecraft", - hostname: "segment-integrations.github.io", - hash: "#/home-collection/Timecraft" - } - } -}] - -const signals = new WebSignalsRuntime(mockSignalBuffer) - -const networkSignal = signals.find(null, 'network') - -``` -### Importing the signals runtime a JS string -```ts -import { getRuntimeCode, getMobileRuntimeCode } from '@segment/analytics-signals-runtime' - -eval(` - ${getMobileRuntimeCode()} - signals.signalBuffer = [....] - `) -``` - -### API documentation -For all exports, explore [the index.ts](src/index.ts). - -### Development -`yarn build` generate the following artifacts: -| Generated File(s) | Description | -|--------|-------------| -| `/dist/runtime/index.[platform].js`, `/[platform]/get-runtime-code.generated.js` | Exposes `globalThis.Signals` and constants (e.g. `SignalType`), either through the script tag or in the mobile JS engine | -| `/dist/editor/[platform]-editor.d.ts.txt` | Type definitions for monaco editor on app.segment.com -| `/dist/esm/index.js` | Entry point for `@segment/analytics-signals` and the segment app, for consumers that want to consume the types / runtime code as an npm package. | diff --git a/packages/signals/signals-runtime/api-extractor.base.json b/packages/signals/signals-runtime/api-extractor.base.json deleted file mode 100644 index ff771d28d..000000000 --- a/packages/signals/signals-runtime/api-extractor.base.json +++ /dev/null @@ -1,33 +0,0 @@ -{ - "$schema": "https://developer.microsoft.com/json-schemas/api-extractor/v7/api-extractor.schema.json", - "compiler": { - "tsconfigFilePath": "./tsconfig.build.json" - }, - "messages": { - "compilerMessageReporting": { - "default": { - "logLevel": "none" - } - }, - "extractorMessageReporting": { - "default": { - "logLevel": "none" - }, - "ae-missing-release-tag": { - "logLevel": "none" - }, - "ae-internal-missing-underscore": { - "logLevel": "none" - }, - "ae-forgotten-export": { - "logLevel": "none" - } - } - }, - "apiReport": { - "enabled": false - }, - "docModel": { - "enabled": false - } -} diff --git a/packages/signals/signals-runtime/api-extractor.mobile.json b/packages/signals/signals-runtime/api-extractor.mobile.json deleted file mode 100644 index 2fdf092dc..000000000 --- a/packages/signals/signals-runtime/api-extractor.mobile.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "extends": "./api-extractor.base.json", - "mainEntryPointFilePath": "./dist/types/mobile/index.mobile-editor.d.ts", - "dtsRollup": { - "enabled": true, - "untrimmedFilePath": "./dist/editor/mobile-editor.d.ts.txt" - } -} diff --git a/packages/signals/signals-runtime/api-extractor.web.json b/packages/signals/signals-runtime/api-extractor.web.json deleted file mode 100644 index 84d46b927..000000000 --- a/packages/signals/signals-runtime/api-extractor.web.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "extends": "./api-extractor.base.json", - "mainEntryPointFilePath": "./dist/types/web/index.web-editor.d.ts", - "dtsRollup": { - "enabled": true, - "untrimmedFilePath": "./dist/editor/web-editor.d.ts.txt" - } -} diff --git a/packages/signals/signals-runtime/build-editor-types.js b/packages/signals/signals-runtime/build-editor-types.js deleted file mode 100644 index a88664590..000000000 --- a/packages/signals/signals-runtime/build-editor-types.js +++ /dev/null @@ -1,48 +0,0 @@ -/* eslint-disable no-undef */ -const { execSync } = require('child_process') -const fsPromises = require('fs').promises -const pkgJSON = require('./package.json') -async function prependGenerated(filePath) { - const content = [ - '/* eslint-disable */', - '// These types will be used in the segment app UI for autocomplete', - `// Generated from: ${pkgJSON.name}@${pkgJSON.version}`, - '// Built as text so they do not cause global scope pollution for packages importing unrelated modules', - '\n', - ].join('\n') - try { - const fileContent = await fsPromises.readFile(filePath, 'utf8') - await fsPromises.writeFile(filePath, content + fileContent) - } catch (error) { - console.error(`Error prepending generated content: ${error}`) - } -} - -async function removeExports(filePath) { - try { - const data = await fsPromises.readFile(filePath, 'utf8') - // Remove 'export { }' lines and any instance of the word 'export' - let result = data - .split('\n') - .filter((line) => line.trim() !== 'export { }') // Remove lines that are exactly 'export { }' - .map((line) => line.replace(/\bexport\b/g, '')) // Remove any instance of the word 'export' - .join('\n') - await fsPromises.writeFile(filePath, result, 'utf8') - } catch (error) { - console.error(`Error exports: ${error}`) - } -} - -const main = async () => { - execSync('yarn build:esm', { stdio: 'inherit' }) - execSync('npx api-extractor run --config ./api-extractor.mobile.json --local') - execSync('npx api-extractor run --config ./api-extractor.web.json --local') - const outputs = [ - './dist/editor/web-editor.d.ts.txt', - './dist/editor/mobile-editor.d.ts.txt', - ] - await Promise.all(outputs.map(removeExports)) - await Promise.all(outputs.map(prependGenerated)) - console.log('wrote:', outputs.join(', ')) -} -main() diff --git a/packages/signals/signals-runtime/build-signals-runtime-global.js b/packages/signals/signals-runtime/build-signals-runtime-global.js deleted file mode 100644 index 44658cdf7..000000000 --- a/packages/signals/signals-runtime/build-signals-runtime-global.js +++ /dev/null @@ -1,122 +0,0 @@ -const esbuild = require('esbuild') -const path = require('path') -const fs = require('fs') -const fsPromises = fs.promises -const babel = require('esbuild-plugin-babel-cjs') - -const getBanner = (entryPoint) => { - const content = [ - `// GENERATED, DO NOT EDIT`, - `// Entry point: ${entryPoint}`, - ].join('\n') - return content -} - -/** - * - * @param {"web" | "mobile"} platform - */ -const getEntryPoint = (platform) => { - return `src/${platform}/index.signals-runtime.ts` -} - -const getOutFiles = (platform) => { - const outfileMinified = `./dist/runtime/index.${platform}.min.js` - const outfileUnminified = `./dist/runtime/index.${platform}.js` - return { - outfileMinified, - outfileUnminified, - } -} - -async function prependContent(filePath, content) { - try { - const fileContent = await fs.promises.readFile(filePath, 'utf8') - await fsPromises.writeFile(filePath, content + '\n' + fileContent) - } catch (error) { - console.error(`Error prepending generated content: ${error}`) - } -} - -const buildRuntimeAsString = async (platform) => { - const banner = getBanner(getEntryPoint(platform)) - const { outfileMinified } = getOutFiles(platform) - - const runtimeContent = fs - .readFileSync(outfileMinified, 'utf-8') - .replace(banner, '') // remove existing banner from code section to be added back later - const generatedDir = path.resolve(__dirname, `src/${platform}`) - if (!fs.existsSync(generatedDir)) { - fs.mkdirSync(generatedDir, { recursive: true }) - } - - const generatedTsFile = `./src/${platform}/get-runtime-code.generated.ts` - const tsFileContent = `export const getRuntimeCode = (): string => \`${runtimeContent}\` - ` - - fs.writeFileSync(generatedTsFile, tsFileContent) - - // add back banner - await prependContent( - generatedTsFile, - ['/* eslint-disable */', banner].join('\n') - ) - console.log(`wrote: ${generatedTsFile}`) -} - -const buildRuntime = async (platform) => { - const entryPoint = getEntryPoint(platform) - const { outfileUnminified, outfileMinified } = getOutFiles(platform) - - const babelPlugin = babel({ - config: { - presets: [ - [ - '@babel/preset-env', - { - targets: { - ie: '11', // target es5 -- for example, react-native's QuickJS does not support class - }, - }, - ], - '@babel/preset-typescript', - ], - }, - }) - // Bundle and minify with esbuild - await esbuild.build({ - entryPoints: [entryPoint], - outfile: outfileMinified, - bundle: true, - minify: true, - banner: { js: getBanner(entryPoint) }, - plugins: [babelPlugin], - }) - console.log(`wrote: ${outfileMinified}`) - - // Bundle without minification - await esbuild.build({ - entryPoints: [entryPoint], - outfile: outfileUnminified, - bundle: true, - minify: false, - banner: { js: getBanner(entryPoint) }, - plugins: [babelPlugin], - }) - console.log(`wrote: ${outfileUnminified}`) -} - -const buildAll = async () => { - const PLATFORMS = ['web', 'mobile'] - for (const platform of PLATFORMS) { - try { - await buildRuntime(platform) - await buildRuntimeAsString(platform) - } catch (err) { - console.error(err) - process.exit(1) - } - } -} - -buildAll() diff --git a/packages/signals/signals-runtime/bundle-build-tests/runtime-env.test.ts b/packages/signals/signals-runtime/bundle-build-tests/runtime-env.test.ts deleted file mode 100644 index 54bf789db..000000000 --- a/packages/signals/signals-runtime/bundle-build-tests/runtime-env.test.ts +++ /dev/null @@ -1,73 +0,0 @@ -import { JSDOM } from 'jsdom' -import fs from 'node:fs' -import path from 'node:path' - -describe('Global Scope Test: Web', () => { - let dom: JSDOM - beforeAll(() => { - // Load the built file - const filePath = path.resolve(__dirname, '../dist/runtime/index.web.js') - const scriptContent = fs.readFileSync(filePath, 'utf-8') - - // Create a new JSDOM instance - dom = new JSDOM(``, { - runScripts: 'dangerously', - resources: 'usable', - }) - - // Execute the script in the JSDOM context - const scriptElement = dom.window.document.createElement('script') - scriptElement.textContent = scriptContent - dom.window.document.head.appendChild(scriptElement) - }) - - test('should expose a signals instance in the global scope', () => { - // @ts-ignore - expect(dom.window).toBeDefined() - // @ts-ignore - expect(typeof dom.window.signals).toBe('object') - expect(typeof dom.window.signals.find).toBe('function') - expect(typeof dom.window.signals.filter).toBe('function') - }) - - test('should expose constants', () => { - expect(dom.window.EventType.Track).toBe('track') - expect(dom.window.NavigationAction.URLChange).toBe('urlChange') - expect(dom.window.SignalType.Interaction).toBe('interaction') - }) -}) - -describe('Global Scope Test: Mobile', () => { - let dom: JSDOM - beforeAll(() => { - // Load the built file - const filePath = path.resolve(__dirname, '../dist/runtime/index.mobile.js') - const scriptContent = fs.readFileSync(filePath, 'utf-8') - - // Create a new JSDOM instance - dom = new JSDOM(``, { - runScripts: 'dangerously', - resources: 'usable', - }) - - // Execute the script in the JSDOM context - const scriptElement = dom.window.document.createElement('script') - scriptElement.textContent = scriptContent - dom.window.document.head.appendChild(scriptElement) - }) - - test('should expose signals in the global scope', () => { - // @ts-ignore - expect(dom.window).toBeDefined() - // @ts-ignore - expect(typeof dom.window.signals).toBe('object') - expect(typeof dom.window.signals.find).toBe('function') - expect(typeof dom.window.signals.filter).toBe('function') - }) - - test('should expose constants', () => { - expect(dom.window.EventType.Track).toBe('track') - expect(dom.window.NavigationAction.Forward).toBe('forward') - expect(dom.window.SignalType.Interaction).toBe('interaction') - }) -}) diff --git a/packages/signals/signals-runtime/jest.config.js b/packages/signals/signals-runtime/jest.config.js deleted file mode 100644 index 824e08ca5..000000000 --- a/packages/signals/signals-runtime/jest.config.js +++ /dev/null @@ -1,6 +0,0 @@ -const { createJestTSConfig } = require('@internal/config') - -module.exports = createJestTSConfig(__dirname, { - testEnvironment: 'jsdom', - setupFilesAfterEnv: ['./jest.setup.js'], -}) diff --git a/packages/signals/signals-runtime/jest.setup.js b/packages/signals/signals-runtime/jest.setup.js deleted file mode 100644 index 65d0a93b2..000000000 --- a/packages/signals/signals-runtime/jest.setup.js +++ /dev/null @@ -1,9 +0,0 @@ -const fetch = require('node-fetch') -const { TextEncoder, TextDecoder } = require('util') - -// fix: "ReferenceError: TextEncoder is not defined" after upgrading JSDOM -global.TextEncoder = TextEncoder -global.TextDecoder = TextDecoder - -// eslint-disable-next-line no-undef -globalThis.fetch = fetch // polyfill fetch so nock will work correctly on node 18 (https://github.com/nock/nock/issues/2336) diff --git a/packages/signals/signals-runtime/package.json b/packages/signals/signals-runtime/package.json deleted file mode 100644 index 42f3d9dfd..000000000 --- a/packages/signals/signals-runtime/package.json +++ /dev/null @@ -1,56 +0,0 @@ -{ - "name": "@segment/analytics-signals-runtime", - "version": "1.5.1", - "keywords": [ - "segment" - ], - "license": "Twilio Software Development Kit License Agreement 2.0", - "main": "./dist/cjs/index.js", - "module": "./dist/esm/index.js", - "types": "./dist/types/index.d.ts", - "files": [ - "LICENSE", - "dist/", - "src/", - "!**/__tests__/**", - "!**/test-helpers/**", - "!*.tsbuildinfo" - ], - "scripts": { - ".": "yarn run -T turbo run --filter=@segment/analytics-signals-runtime...", - "test": "yarn jest", - "lint": "yarn concurrently 'yarn:eslint .' 'yarn:tsc --noEmit'", - "build": "rm -rf dist && yarn concurrently 'yarn:build:*'", - "build:editor": "node build-editor-types.js", - "build:esm": "yarn tsc -p tsconfig.build.json", - "build:cjs": "yarn tsc -p tsconfig.build.json --outDir ./dist/cjs --module commonjs", - "build:global": "node build-signals-runtime-global.js", - "assert-generated": "bash scripts/assert-generated.sh", - "watch": "rm -rf dist/esm && yarn build:esm && yarn build:esm --watch", - "watch:test": "yarn test --watch", - "tsc": "yarn run -T tsc", - "eslint": "yarn run -T eslint", - "concurrently": "yarn run -T concurrently", - "jest": "yarn run -T jest", - "webpack": "yarn run -T webpack" - }, - "dependencies": { - "tslib": "^2.4.1" - }, - "packageManager": "yarn@3.4.1", - "repository": { - "directory": "packages/signals/signals-runtime", - "type": "git", - "url": "https://github.com/segmentio/analytics-next" - }, - "devDependencies": { - "@babel/cli": "^7.22.10", - "@babel/core": "^7.22.11", - "@babel/preset-env": "^7.22.10", - "@babel/preset-typescript": "^7.22.11", - "@internal/test-helpers": "workspace:^", - "@microsoft/api-extractor": "^7.47.9", - "babel-preset-minify": "^0.5.2", - "esbuild-plugin-babel-cjs": "^1.0.0" - } -} diff --git a/packages/signals/signals-runtime/scripts/assert-generated.sh b/packages/signals/signals-runtime/scripts/assert-generated.sh deleted file mode 100644 index 66f9719ca..000000000 --- a/packages/signals/signals-runtime/scripts/assert-generated.sh +++ /dev/null @@ -1,17 +0,0 @@ -#!/bin/sh -# A CI script to ensure people remember to rebuild workerbox related files if workerbox changes - -yarn build:global - -# Check for changes in the workerbox directory -changed_files=$(git diff --name-only | grep 'generated') - -# Check for changes in the workerbox directory -if [ -n "$changed_files" ]; then - echo "Error: Changes detected. Please commit the changed files:" - echo "$changed_files" - exit 1 -else - echo "Files have not changed" - exit 0 -fi diff --git a/packages/signals/signals-runtime/src/__tests__/signals-runtime.test.ts b/packages/signals/signals-runtime/src/__tests__/signals-runtime.test.ts deleted file mode 100644 index 7d9024b89..000000000 --- a/packages/signals/signals-runtime/src/__tests__/signals-runtime.test.ts +++ /dev/null @@ -1,118 +0,0 @@ -import { InstrumentationSignal, InteractionSignal, Signal } from '../index' -import { - mockInstrumentationSignal, - mockInteractionSignal, - mockPageData, -} from '../test-helpers/mocks/mock-signal-types-web' - -import { WebSignalsRuntime } from '../web/web-signals-runtime' -describe(WebSignalsRuntime, () => { - let signalsRuntime: WebSignalsRuntime - let signal1: InstrumentationSignal - let signal2: InteractionSignal - let signal3: InteractionSignal - let mockSignals: Signal[] = [] - beforeEach(() => { - signal1 = mockInstrumentationSignal - signal2 = mockInteractionSignal - signal3 = { - ...mockInteractionSignal, - data: { - page: mockPageData, - eventType: 'change', - target: {} as any, - change: {}, - listener: 'onchange', - }, - } - mockSignals = [signal1, signal2, signal3] - signalsRuntime = new WebSignalsRuntime(mockSignals) - }) - - describe('meta', () => { - it('should be serializable / iterable', () => { - const copy = { ...signalsRuntime } - expect(copy).toMatchObject({ - find: expect.any(Function), - filter: expect.any(Function), - }) - }) - }) - - describe('find', () => { - it('should find following signal based on the provided function', () => { - const result = signalsRuntime.find(signal2, 'interaction', () => true) - expect(result).toEqual(signal3) - }) - - it('should return undefined if there are no following signals that match the query', () => { - const result = signalsRuntime.find(signal1, 'instrumentation', () => true) - expect(result).toEqual(undefined) - }) - - it('should filter based on predicate', () => { - const result = signalsRuntime.find( - signal1, - 'interaction', - (signal) => signal.data.eventType === 'change' - ) - expect(result).toEqual(signal3) - }) - - it('should return the first match if predicate is not provided', () => { - const result = signalsRuntime.find(signal1, 'interaction') - expect(result).toEqual(signal2) - }) - }) - - describe('filter', () => { - it('should filter based on the provided function', () => { - const result = signalsRuntime.filter(signal2, 'interaction', () => true) - expect(result).toEqual([signal3]) - }) - - it('should return an empty array if there are no following signals that match the query', () => { - const result = signalsRuntime.filter( - signal1, - 'instrumentation', - () => true - ) - expect(result).toEqual([]) - }) - - it('should filter based on predicate', () => { - const result = signalsRuntime.filter( - signal1, - 'interaction', - (signal) => signal.data.eventType === 'change' - ) - expect(result).toEqual([signal3]) - }) - - it('should return all matches if predicate is not provided', () => { - const result = signalsRuntime.filter(signal1, 'interaction') - expect(result).toEqual([signal2, signal3]) - }) - }) - - describe('signalBuffer property', () => { - beforeEach(() => { - signalsRuntime = new WebSignalsRuntime() - }) - it('should have no signals by default', () => { - expect(signalsRuntime.signalBuffer).toEqual([]) - }) - it('should let you set the signal buffer', () => { - signalsRuntime = new WebSignalsRuntime() - const newSignal = mockInstrumentationSignal - signalsRuntime.signalBuffer = [newSignal] - expect(signalsRuntime.signalBuffer).toEqual([newSignal]) - }) - - it('should support find, etc', () => { - signalsRuntime.signalBuffer = mockSignals - const result = signalsRuntime.find(signal2, 'interaction', () => true) - expect(result).toEqual(signal3) - }) - }) -}) diff --git a/packages/signals/signals-runtime/src/index.ts b/packages/signals/signals-runtime/src/index.ts deleted file mode 100644 index 7c4148ac7..000000000 --- a/packages/signals/signals-runtime/src/index.ts +++ /dev/null @@ -1,17 +0,0 @@ -// This file is only for people who plan on installing this package in their npm projects, like us. - -// shared -export { SignalsRuntime } from './shared/signals-runtime' - -// web -export * from './web/web-signals-types' -export * from './shared/shared-types' -export * as WebRuntimeConstants from './web/web-constants' -export { getRuntimeCode } from './web/get-runtime-code.generated' -export { WebSignalsRuntime } from './web/web-signals-runtime' - -// mobile -- we don't need this *yet*, but some day? -export * as Mobile from './mobile/mobile-signals-types' -export * as MobileRuntimeConstants from './mobile/mobile-constants' -export { MobileSignalsRuntime } from './mobile/mobile-signals-runtime' -export { getRuntimeCode as getMobileRuntimeCode } from './mobile/get-runtime-code.generated' diff --git a/packages/signals/signals-runtime/src/mobile/get-runtime-code.generated.ts b/packages/signals/signals-runtime/src/mobile/get-runtime-code.generated.ts deleted file mode 100644 index 30a32abcf..000000000 --- a/packages/signals/signals-runtime/src/mobile/get-runtime-code.generated.ts +++ /dev/null @@ -1,7 +0,0 @@ -/* eslint-disable */ -// GENERATED, DO NOT EDIT -// Entry point: src/mobile/index.signals-runtime.ts -export const getRuntimeCode = (): string => ` -"use strict";(()=>{var w=Object.defineProperty;var P=(t,e)=>{for(var r in e)w(t,r,{get:e[r],enumerable:!0})};var l={};P(l,{EventType:()=>j,LocalDataAction:()=>B,NavigationAction:()=>R,NetworkAction:()=>T,SignalType:()=>x});var x=Object.freeze({Interaction:"interaction",Navigation:"navigation",Network:"network",LocalData:"localData",Instrumentation:"instrumentation",UserDefined:"userDefined"}),j=Object.freeze({Track:"track",Page:"page",Screen:"screen",Identify:"identify",Group:"group",Alias:"alias"}),R=Object.freeze({Forward:"forward",Backward:"backward",Modal:"modal",Entering:"entering",Leaving:"leaving",Page:"page",Popup:"popup"}),T=Object.freeze({Request:"request",Response:"response"}),B=Object.freeze({Loaded:"loaded",Updated:"updated",Saved:"saved",Deleted:"deleted",Undefined:"undefined"});function a(t){"@babel/helpers - typeof";return a=typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?function(e){return typeof e}:function(e){return e&&typeof Symbol=="function"&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},a(t)}function p(t,e){for(var r=0;r0&&arguments[0]!==void 0?arguments[0]:[];E(this,t),b(this,"find",function(n,o,i){return e.filter(n,o,i)[0]}),b(this,"filter",function(n,o,i){var S=function(O){return O.type===o};return e.signalBuffer.slice(e.signalBuffer.indexOf(n)+1).filter(S).filter(function(y){return i?i(y):function(){return!0}})}),this.signalBuffer=r});function f(t){"@babel/helpers - typeof";return f=typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?function(e){return typeof e}:function(e){return e&&typeof Symbol=="function"&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},f(t)}function d(t,e){for(var r=0;r"u"||!Reflect.construct||Reflect.construct.sham)return!1;if(typeof Proxy=="function")return!0;try{return Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],function(){})),!0}catch{return!1}}function u(t){return u=Object.setPrototypeOf?Object.getPrototypeOf.bind():function(r){return r.__proto__||Object.getPrototypeOf(r)},u(t)}function v(t,e,r){return e=h(e),e in t?Object.defineProperty(t,e,{value:r,enumerable:!0,configurable:!0,writable:!0}):t[e]=r,t}function h(t){var e=C(t,"string");return f(e)==="symbol"?e:String(e)}function C(t,e){if(f(t)!=="object"||t===null)return t;var r=t[Symbol.toPrimitive];if(r!==void 0){var n=r.call(t,e||"default");if(f(n)!=="object")return n;throw new TypeError("@@toPrimitive must return a primitive value.")}return(e==="string"?String:Number)(t)}var _=function(t){k(r,t);var e=A(r);function r(){var n,o=arguments.length>0&&arguments[0]!==void 0?arguments[0]:[];return I(this,r),n=e.call(this,o),v(s(n),"add",function(i){n.signalCounter<0&&(n.signalCounter=0),"index"in i&&i.index==-1&&(i.index=n.getNextIndex()),n.signalBuffer.unshift(i),n.signalBuffer.length>n.maxBufferSize&&n.signalBuffer.pop()}),v(s(n),"getNextIndex",function(){var i=n.signalCounter;return n.signalCounter+=1,i}),n.signalCounter=0,n.maxBufferSize=1e3,n}return D(r)}(m);Object.assign(globalThis,{signals:new _},l);})(); -` - \ No newline at end of file diff --git a/packages/signals/signals-runtime/src/mobile/index.mobile-editor.ts b/packages/signals/signals-runtime/src/mobile/index.mobile-editor.ts deleted file mode 100644 index c3e5d72a4..000000000 --- a/packages/signals/signals-runtime/src/mobile/index.mobile-editor.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { MobileSignalsRuntime } from './mobile-signals-runtime' -export { MobileSignalsRuntime } - -export const signals = new MobileSignalsRuntime() - -/** - * Entry point for the editor definitions - */ -export * from './mobile-signals-types' -export * from '../shared/shared-types' -export * from './mobile-constants' diff --git a/packages/signals/signals-runtime/src/mobile/index.signals-runtime.ts b/packages/signals/signals-runtime/src/mobile/index.signals-runtime.ts deleted file mode 100644 index 8d5373eee..000000000 --- a/packages/signals/signals-runtime/src/mobile/index.signals-runtime.ts +++ /dev/null @@ -1,13 +0,0 @@ -import * as Constants from './mobile-constants' -import { MobileSignalsRuntime } from './mobile-signals-runtime' - -// assign SignalsRuntime and all constants to globalThis -// meant to replace this: -// https://github.com/segmentio/SignalsJS-Runtime/blob/main/Runtime/Signals.js -Object.assign( - globalThis, - { - signals: new MobileSignalsRuntime(), - }, - Constants -) diff --git a/packages/signals/signals-runtime/src/mobile/mobile-constants.ts b/packages/signals/signals-runtime/src/mobile/mobile-constants.ts deleted file mode 100644 index 48e6665ec..000000000 --- a/packages/signals/signals-runtime/src/mobile/mobile-constants.ts +++ /dev/null @@ -1,40 +0,0 @@ -export const SignalType = Object.freeze({ - Interaction: 'interaction', - Navigation: 'navigation', - Network: 'network', - LocalData: 'localData', - Instrumentation: 'instrumentation', - UserDefined: 'userDefined', -}) - -export const EventType = Object.freeze({ - Track: 'track', - Page: 'page', - Screen: 'screen', - Identify: 'identify', - Group: 'group', - Alias: 'alias', -}) - -export const NavigationAction = Object.freeze({ - Forward: 'forward', - Backward: 'backward', - Modal: 'modal', - Entering: 'entering', - Leaving: 'leaving', - Page: 'page', - Popup: 'popup', -}) - -export const NetworkAction = Object.freeze({ - Request: 'request', - Response: 'response', -}) - -export const LocalDataAction = Object.freeze({ - Loaded: 'loaded', - Updated: 'updated', - Saved: 'saved', - Deleted: 'deleted', - Undefined: 'undefined', -}) diff --git a/packages/signals/signals-runtime/src/mobile/mobile-signals-runtime.ts b/packages/signals/signals-runtime/src/mobile/mobile-signals-runtime.ts deleted file mode 100644 index 0ec4b1d49..000000000 --- a/packages/signals/signals-runtime/src/mobile/mobile-signals-runtime.ts +++ /dev/null @@ -1,33 +0,0 @@ -import { SignalsRuntime } from '../shared/signals-runtime' -import { Signal } from './mobile-signals-types' - -export class MobileSignalsRuntime extends SignalsRuntime { - private signalCounter: number - private maxBufferSize: number - constructor(signals: Signal[] = []) { - super(signals) - this.signalCounter = 0 - this.maxBufferSize = 1000 - } - add = (signal: Signal) => { - if (this.signalCounter < 0) { - this.signalCounter = 0 - } - - if ('index' in signal && signal.index == -1) { - // this was previously broken for ages, not sure when this code path would ever be used. - // My understanding is that currently, getNextIndex() is called _outside_ of this function and used to construct the added signal. - seth - signal.index = this.getNextIndex() - } - this.signalBuffer.unshift(signal) - if (this.signalBuffer.length > this.maxBufferSize) { - this.signalBuffer.pop() - } - } - - getNextIndex = () => { - const index = this.signalCounter - this.signalCounter += 1 - return index - } -} diff --git a/packages/signals/signals-runtime/src/mobile/mobile-signals-types.ts b/packages/signals/signals-runtime/src/mobile/mobile-signals-types.ts deleted file mode 100644 index ec9544796..000000000 --- a/packages/signals/signals-runtime/src/mobile/mobile-signals-types.ts +++ /dev/null @@ -1,90 +0,0 @@ -import { BaseSignal } from '../shared/shared-types' - -export type SignalTypes = Signal['type'] - -export type NavigationActionName = - | 'forward' - | 'backward' - | 'modal' - | 'entering' - | 'leaving' - | 'page' - | 'popup' - -export type NetworkActionName = 'request' | 'response' - -export type LocalDataActionName = - | 'loaded' - | 'updated' - | 'saved' - | 'deleted' - | 'undefined' - -export type Signal = - | InteractionSignal - | NavigationSignal - | NetworkSignal - | LocalDataSignal - | InstrumentationSignal - | UserDefinedSignal - -interface RawSignal extends BaseSignal { - type: SignalType - anonymousId: string - data: any - timestamp: string - index: any -} - -interface NavigationData { - action: NavigationActionName - screen: string -} - -interface NavigationSignal extends RawSignal<'navigation'> { - data: NavigationData -} - -interface InteractionData { - component: string - info: string - data: any -} - -interface InteractionSignal extends RawSignal<'interaction'> { - type: 'interaction' - data: InteractionData -} - -interface NetworkData { - action: NetworkActionName - url: string - data: any -} - -interface NetworkSignal extends RawSignal<'network'> { - data: NetworkData -} - -interface LocalData { - action: LocalDataActionName - identifier: string - data: string -} - -interface LocalDataSignal extends RawSignal<'localData'> { - data: LocalData -} - -interface UserDefinedSignal extends RawSignal<'userDefined'> { - data: any -} - -interface InstrumentationData { - type: 'instrumentation' - rawEvent: any -} - -interface InstrumentationSignal extends RawSignal<'instrumentation'> { - data: InstrumentationData -} diff --git a/packages/signals/signals-runtime/src/shared/shared-types.ts b/packages/signals/signals-runtime/src/shared/shared-types.ts deleted file mode 100644 index fb863fc2f..000000000 --- a/packages/signals/signals-runtime/src/shared/shared-types.ts +++ /dev/null @@ -1,25 +0,0 @@ -export type ID = string | null | undefined - -export interface BaseSignal { - type: string - anonymousId: ID - timestamp: string -} - -export type SignalOfType< - AllSignals extends BaseSignal, - SignalType extends AllSignals['type'] -> = AllSignals & { type: SignalType } - -export type JSONPrimitive = string | number | boolean | null -export type JSONValue = JSONPrimitive | JSONObject | JSONArray -export type JSONObject = { [member: string]: JSONValue } -export type JSONArray = JSONValue[] - -export interface SegmentEvent { - /** - * @example 'track' | 'page' | 'screen' | 'identify' | 'group' | 'alias' - */ - type: string - [key: string]: unknown -} diff --git a/packages/signals/signals-runtime/src/shared/signals-runtime.ts b/packages/signals/signals-runtime/src/shared/signals-runtime.ts deleted file mode 100644 index 513205fbb..000000000 --- a/packages/signals/signals-runtime/src/shared/signals-runtime.ts +++ /dev/null @@ -1,52 +0,0 @@ -import { BaseSignal, SignalOfType } from '../shared/shared-types' - -/** - * Base class that provides runtime utilities for signals. - */ -export abstract class SignalsRuntime { - signalBuffer: Signal[] - - constructor(signals: Signal[] = []) { - // initial signals - this.signalBuffer = signals - } - - /** - * Finds a signal of a specific type from a given signal. - * - * SignalType - The type of the signal to find. - * @param fromSignal - The signal to search from. - * @param signalType - The type of the signal to find. - * @param predicate - Optional predicate function to filter the signals. - * @returns The found signal of the specified type, or undefined if not found. - */ - find = ( - fromSignal: Signal, - signalType: SignalType, - predicate?: (signal: SignalOfType) => boolean - ): SignalOfType | undefined => { - return this.filter(fromSignal, signalType, predicate)[0] - } - - /** - * Filters signals of a specific type from a given signal. - * SignalType - The type of the signals to filter. - * @param fromSignal - The signal to search from. - * @param signalType - The type of the signals to filter. - * @param predicate - Optional predicate function to filter the signals. - * @returns An array of signals of the specified type. - */ - filter = ( - fromSignal: Signal, - signalType: SignalType, - predicate?: (signal: SignalOfType) => boolean - ): SignalOfType[] => { - const _isSignalOfType = ( - signal: Signal - ): signal is SignalOfType => signal.type === signalType - return this.signalBuffer - .slice(this.signalBuffer.indexOf(fromSignal) + 1) - .filter(_isSignalOfType) - .filter((signal) => (predicate ? predicate(signal) : () => true)) - } -} diff --git a/packages/signals/signals-runtime/src/test-helpers/mocks/mock-signal-types-web.ts b/packages/signals/signals-runtime/src/test-helpers/mocks/mock-signal-types-web.ts deleted file mode 100644 index e1f5b10d0..000000000 --- a/packages/signals/signals-runtime/src/test-helpers/mocks/mock-signal-types-web.ts +++ /dev/null @@ -1,87 +0,0 @@ -import { BaseSignal } from '../../shared/shared-types' -import { - InteractionSignal, - NavigationSignal, - InstrumentationSignal, - UserDefinedSignal, - NetworkSignal, - PageData, -} from '../../web/web-signals-types' -// Mock data for testing - -type DefaultProps = Pick - -const baseSignalProps: DefaultProps = { - anonymousId: '123', - timestamp: '2020-01-01T00:00:00.000Z', -} - -export const mockPageData: PageData = { - url: 'https://www.segment.com/docs/connections/sources/catalog/libraries/website/javascript/', - path: '/docs/connections/sources/catalog/libraries/website/javascript/', - search: '', - hostname: 'www.segment.com', - hash: '', - referrer: '', - title: 'Segment - Documentation', -} - -export const mockInteractionSignal: InteractionSignal = { - type: 'interaction', - data: { - page: mockPageData, - eventType: 'click', - target: { - id: 'button1', - className: 'btn-primary', - attributes: { id: 'button1', class: 'btn-primary' }, - }, - }, - ...baseSignalProps, -} - -export const mockNavigationSignal: NavigationSignal = { - type: 'navigation', - data: { - action: 'urlChange', - changedProperties: ['path'], - page: mockPageData, - path: '/', - search: '', - url: 'https://example.com', - hash: '#section1', - prevUrl: 'https://example.com/home', - }, - ...baseSignalProps, -} - -export const mockInstrumentationSignal: InstrumentationSignal = { - type: 'instrumentation', - data: { - page: mockPageData, - rawEvent: { type: 'customEvent', detail: 'example' }, - }, - ...baseSignalProps, -} - -export const mockNetworkSignal: NetworkSignal = { - type: 'network', - data: { - page: mockPageData, - action: 'request', - contentType: 'application/json', - url: 'https://api.example.com/data', - method: 'GET', - data: { key: 'value' }, - }, - ...baseSignalProps, -} - -export const mockUserDefinedSignal: UserDefinedSignal = { - type: 'userDefined', - data: { - page: mockPageData, - customField: 'customValue', - }, - ...baseSignalProps, -} diff --git a/packages/signals/signals-runtime/src/web/get-runtime-code.generated.ts b/packages/signals/signals-runtime/src/web/get-runtime-code.generated.ts deleted file mode 100644 index 2c8388f2a..000000000 --- a/packages/signals/signals-runtime/src/web/get-runtime-code.generated.ts +++ /dev/null @@ -1,7 +0,0 @@ -/* eslint-disable */ -// GENERATED, DO NOT EDIT -// Entry point: src/web/index.signals-runtime.ts -export const getRuntimeCode = (): string => ` -"use strict";(()=>{var S=Object.defineProperty;var O=(t,e)=>{for(var r in e)S(t,r,{get:e[r],enumerable:!0})};function u(t){"@babel/helpers - typeof";return u=typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?function(e){return typeof e}:function(e){return e&&typeof Symbol=="function"&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},u(t)}function s(t,e){for(var r=0;r0&&arguments[0]!==void 0?arguments[0]:[];d(this,t),b(this,"find",function(n,i,o){return e.filter(n,i,o)[0]}),b(this,"filter",function(n,i,o){var h=function(_){return _.type===i};return e.signalBuffer.slice(e.signalBuffer.indexOf(n)+1).filter(h).filter(function(y){return o?o(y):function(){return!0}})}),this.signalBuffer=r});function f(t){"@babel/helpers - typeof";return f=typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?function(e){return typeof e}:function(e){return e&&typeof Symbol=="function"&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},f(t)}function g(t,e){for(var r=0;r"u"||!Reflect.construct||Reflect.construct.sham)return!1;if(typeof Proxy=="function")return!0;try{return Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],function(){})),!0}catch{return!1}}function a(t){return a=Object.setPrototypeOf?Object.getPrototypeOf.bind():function(r){return r.__proto__||Object.getPrototypeOf(r)},a(t)}var v=function(t){E(r,t);var e=N(r);function r(){return x(this,r),e.apply(this,arguments)}return j(r)}(m);var c={};O(c,{EventType:()=>I,NavigationAction:()=>z,SignalType:()=>L});var I=Object.freeze({Track:"track",Page:"page",Screen:"screen",Identify:"identify",Group:"group",Alias:"alias"}),z=Object.freeze({URLChange:"urlChange",PageLoad:"pageLoad"}),L=Object.freeze({Interaction:"interaction",Navigation:"navigation",Network:"network",LocalData:"localData",Instrumentation:"instrumentation",UserDefined:"userDefined"});Object.assign(globalThis,{signals:new v},c);})(); -` - \ No newline at end of file diff --git a/packages/signals/signals-runtime/src/web/index.signals-runtime.ts b/packages/signals/signals-runtime/src/web/index.signals-runtime.ts deleted file mode 100644 index ec958140e..000000000 --- a/packages/signals/signals-runtime/src/web/index.signals-runtime.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { WebSignalsRuntime } from './web-signals-runtime' -import * as Constants from './web-constants' - -// assign SignalsRuntime and all constants to globalThis -Object.assign( - globalThis, - { - signals: new WebSignalsRuntime(), - }, - Constants -) diff --git a/packages/signals/signals-runtime/src/web/index.web-editor.ts b/packages/signals/signals-runtime/src/web/index.web-editor.ts deleted file mode 100644 index 19ab4ab7e..000000000 --- a/packages/signals/signals-runtime/src/web/index.web-editor.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { WebSignalsRuntime } from './web-signals-runtime' -export { WebSignalsRuntime } - -export const signals = new WebSignalsRuntime() - -/** - * Entry point for the editor definitions - */ -export * from './web-signals-types' -export * from '../shared/shared-types' -export * from './web-constants' diff --git a/packages/signals/signals-runtime/src/web/web-constants.ts b/packages/signals/signals-runtime/src/web/web-constants.ts deleted file mode 100644 index 702dc5185..000000000 --- a/packages/signals/signals-runtime/src/web/web-constants.ts +++ /dev/null @@ -1,22 +0,0 @@ -export const EventType = Object.freeze({ - Track: 'track', - Page: 'page', - Screen: 'screen', - Identify: 'identify', - Group: 'group', - Alias: 'alias', -}) - -export const NavigationAction = Object.freeze({ - URLChange: 'urlChange', - PageLoad: 'pageLoad', -}) - -export const SignalType = Object.freeze({ - Interaction: 'interaction', - Navigation: 'navigation', - Network: 'network', - LocalData: 'localData', - Instrumentation: 'instrumentation', - UserDefined: 'userDefined', -}) diff --git a/packages/signals/signals-runtime/src/web/web-signals-runtime.ts b/packages/signals/signals-runtime/src/web/web-signals-runtime.ts deleted file mode 100644 index c80500242..000000000 --- a/packages/signals/signals-runtime/src/web/web-signals-runtime.ts +++ /dev/null @@ -1,4 +0,0 @@ -import { SignalsRuntime } from '../shared/signals-runtime' -import { Signal } from './web-signals-types' - -export class WebSignalsRuntime extends SignalsRuntime {} diff --git a/packages/signals/signals-runtime/src/web/web-signals-types.ts b/packages/signals/signals-runtime/src/web/web-signals-types.ts deleted file mode 100644 index ee3d8fd80..000000000 --- a/packages/signals/signals-runtime/src/web/web-signals-types.ts +++ /dev/null @@ -1,186 +0,0 @@ -import { BaseSignal, JSONValue } from '../shared/shared-types' - -export type SignalTypes = Signal['type'] - -export interface PageData { - /** - * The full URL of the page - * If there is a canonical URL, this should be the canonical URL - * @example https://www.segment.com/docs/connections/sources/catalog/libraries/website/javascript/ - */ - url: string - /** - * The path of the page - * @example /docs/connections/sources/catalog/libraries/website/javascript/ - */ - path: string - /** - * The search parameters of the page - * @example ?utm_source=google - */ - search: string - /** - * The hostname of the page - * @example www.segment.com - */ - hostname: string - /** - * The hash of the page - * @example #hash - */ - hash: string - /** - * The referrer of the page - * @example https://www.google.com/ - */ - referrer: string - /** - * The title of the page - * @example Segment - Documentation - */ - title: string -} - -/** - * The base data that all web signal data must have - */ -export interface BaseWebData { - page: PageData -} - -export interface RawSignal extends BaseSignal { - type: T - data: BaseWebData & Data - metadata?: Record -} -export type InteractionData = ClickData | SubmitData | ChangeData - -export type ParsedAttributes = { [attributeName: string]: string | null } - -export interface TargetedHTMLElement { - id: string - attributes: ParsedAttributes - [key: string]: any -} - -type ClickData = { - eventType: 'click' - target: TargetedHTMLElement -} - -type SubmitData = { - eventType: 'submit' - submitter?: TargetedHTMLElement - target: TargetedHTMLElement -} - -export type ChangeData = { - eventType: 'change' - /** - * The target element that changed. - */ - target: TargetedHTMLElement - /** - * The name/type of "listener" that triggered the change. - * Elements can change due to a variety of reasons, such as a mutation, a change event, or a contenteditable change - */ - listener: 'contenteditable' | 'onchange' | 'mutation' - /** - * The change that occurred -- this is a key-value object of the change that occurred - * For mutation listeners, this is the attributes that changed - * For contenteditable listeners, this is the text that changed - * @example - * ```ts - * { checked: true } // onchange - * { value: 'new value' } // onchange / mutation - * {'aria-selected': 'true' } // mutation - * { textContent: 'Sentence1\nSentence2\n' } // contenteditable - * ``` - */ - change: JSONValue -} - -export type InteractionSignal = RawSignal<'interaction', InteractionData> - -interface BaseNavigationData { - action: ActionType - url: string - hash: string - search: string - path: string -} - -export type ChangedProperties = 'path' | 'search' | 'hash' -export interface URLChangeNavigationData - extends BaseNavigationData<'urlChange'> { - prevUrl: string - changedProperties: ChangedProperties[] -} - -export interface PageChangeNavigationData - extends BaseNavigationData<'pageLoad'> {} - -export type NavigationData = URLChangeNavigationData | PageChangeNavigationData - -export type NavigationSignal = RawSignal<'navigation', NavigationData> - -interface InstrumentationData { - rawEvent: unknown -} -export type InstrumentationSignal = RawSignal< - 'instrumentation', - InstrumentationData -> - -export interface NetworkSignalMetadata { - filters: { - allowed: string[] - disallowed: string[] - } -} - -interface BaseNetworkData { - action: string - url: string - data: JSONValue - contentType: string -} - -interface NetworkRequestData extends BaseNetworkData { - action: 'request' - url: string - method: HTTPMethod -} - -interface NetworkResponseData extends BaseNetworkData { - action: 'response' - url: string - status: number - ok: boolean -} - -export type HTTPMethod = - | 'GET' - | 'POST' - | 'PUT' - | 'DELETE' - | 'PATCH' - | 'HEAD' - | 'OPTIONS' - -export type NetworkData = NetworkRequestData | NetworkResponseData - -export type NetworkSignal = RawSignal<'network', NetworkData> - -export interface UserDefinedSignalData { - [key: string]: any -} - -export type UserDefinedSignal = RawSignal<'userDefined', UserDefinedSignalData> - -export type Signal = - | InteractionSignal - | NavigationSignal - | InstrumentationSignal - | NetworkSignal - | UserDefinedSignal diff --git a/packages/signals/signals-runtime/tsconfig.build.json b/packages/signals/signals-runtime/tsconfig.build.json deleted file mode 100644 index 6b091bfd8..000000000 --- a/packages/signals/signals-runtime/tsconfig.build.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "extends": "./tsconfig.json", - "include": ["src"], - "exclude": ["**/__tests__/**", "**/test-helpers/**"], - "compilerOptions": { - "noEmit": false, - "outDir": "./dist/esm", - "declarationDir": "./dist/types" - } -} diff --git a/packages/signals/signals-runtime/tsconfig.json b/packages/signals/signals-runtime/tsconfig.json deleted file mode 100644 index 5dc03eda1..000000000 --- a/packages/signals/signals-runtime/tsconfig.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "extends": "../../../tsconfig.json", - "exclude": ["node_modules", "dist", "src/generated"], - "compilerOptions": { - "module": "ESNext", // es6 modules - "target": "ES2020", // don't down-compile *too much* -- if users are using webpack, they can always transpile this library themselves - "lib": ["ES2020", "DOM", "DOM.Iterable"], // assume that consumers will be polyfilling at least down to es2020 - "moduleResolution": "node", - - "isolatedModules": true // ensure we are friendly to build systems - } -} diff --git a/packages/signals/signals/package.json b/packages/signals/signals/package.json index aa402a9b2..cc8bed496 100644 --- a/packages/signals/signals/package.json +++ b/packages/signals/signals/package.json @@ -45,7 +45,7 @@ }, "dependencies": { "@segment/analytics-generic-utils": "1.2.0", - "@segment/analytics-signals-runtime": "1.5.1", + "@segment/analytics-signals-runtime": "2.0.0", "idb": "^8.0.0", "tslib": "^2.4.1" }, diff --git a/packages/signals/signals/src/core/analytics-service/__tests__/analytics-service.test.ts b/packages/signals/signals/src/core/analytics-service/__tests__/analytics-service.test.ts index dfc460089..021ab9581 100644 --- a/packages/signals/signals/src/core/analytics-service/__tests__/analytics-service.test.ts +++ b/packages/signals/signals/src/core/analytics-service/__tests__/analytics-service.test.ts @@ -43,6 +43,13 @@ describe(AnalyticsService, () => { expect(call).toMatchInlineSnapshot(` { "anonymousId": "", + "context": { + "library": { + "name": "@segment/analytics-next", + "version": "0.0.0", + }, + "signalsRuntime": "", + }, "data": { "rawEvent": { "context": { @@ -50,7 +57,9 @@ describe(AnalyticsService, () => { }, "type": "track", }, + "type": "track", }, + "index": undefined, "timestamp": , "type": "instrumentation", } diff --git a/packages/signals/signals/src/core/middleware/network-signals-filter/network-signals-filter.ts b/packages/signals/signals/src/core/middleware/network-signals-filter/network-signals-filter.ts index 396169825..8a8e9c649 100644 --- a/packages/signals/signals/src/core/middleware/network-signals-filter/network-signals-filter.ts +++ b/packages/signals/signals/src/core/middleware/network-signals-filter/network-signals-filter.ts @@ -149,13 +149,8 @@ export class NetworkSignalsFilterMiddleware implements SignalsMiddleware { this.filter = new NetworkSignalsFilter(ctx.unstableGlobalSettings.network) } - private createMetadata = () => ({ - filters: this.filter.settings.networkSignalsFilterList.getRegexes(), - }) - process(signal: Signal): Signal | null { if (signal.type === 'network') { - signal.metadata = this.createMetadata() return this.filter.isAllowed(signal.data.url) ? signal : null } else { return signal diff --git a/packages/signals/signals/src/core/middleware/signals-ingest/__tests__/client.test.ts b/packages/signals/signals/src/core/middleware/signals-ingest/__tests__/client.test.ts index 8b7a37584..0e651b7c6 100644 --- a/packages/signals/signals/src/core/middleware/signals-ingest/__tests__/client.test.ts +++ b/packages/signals/signals/src/core/middleware/signals-ingest/__tests__/client.test.ts @@ -46,9 +46,10 @@ describe(SignalsIngestClient, () => { it('makes a network track call via the analytics api', async () => { expect(client).toBeTruthy() const signal = createNetworkSignal({ + requestId: '12345', contentType: 'application/json', action: 'request', - data: { + body: { hello: 'how are you', }, method: 'POST', @@ -59,12 +60,19 @@ describe(SignalsIngestClient, () => { expect(ctx!.event.properties!).toMatchInlineSnapshot(` { "anonymousId": "", + "context": { + "library": { + "name": "@segment/analytics-next", + "version": "0.0.0", + }, + "signalsRuntime": "", + }, "data": { "action": "request", - "contentType": "application/json", - "data": { + "body": { "hello": "XXX", }, + "contentType": "application/json", "method": "POST", "page": { "hash": "", @@ -75,15 +83,10 @@ describe(SignalsIngestClient, () => { "title": "", "url": "http://localhost/", }, + "requestId": "12345", "url": "http://foo.com", }, "index": 0, - "metadata": { - "filters": { - "allowed": [], - "disallowed": [], - }, - }, "timestamp": , "type": "network", } diff --git a/packages/signals/signals/src/core/middleware/signals-ingest/__tests__/redact.test.ts b/packages/signals/signals/src/core/middleware/signals-ingest/__tests__/redact.test.ts index 93b3c5e18..d04a57077 100644 --- a/packages/signals/signals/src/core/middleware/signals-ingest/__tests__/redact.test.ts +++ b/packages/signals/signals/src/core/middleware/signals-ingest/__tests__/redact.test.ts @@ -1,4 +1,3 @@ -import { NetworkSignalMetadata } from '@segment/analytics-signals-runtime' import { createMockTarget } from '../../../../test-helpers/mocks/factories' import * as factories from '../../../../types/factories' import { redactJsonValues, redactSignalData } from '../redact' @@ -59,12 +58,6 @@ describe(redactJsonValues, () => { }) describe(redactSignalData, () => { - const metadataFixture: NetworkSignalMetadata = { - filters: { - allowed: [], - disallowed: [], - }, - } it('should return the signal as is if the type is "instrumentation"', () => { const signal = factories.createInstrumentationSignal({ foo: 123, @@ -137,26 +130,22 @@ describe(redactSignalData, () => { }) it('should redact the values in the "data" property if the type is "network"', () => { - const signal = factories.createNetworkSignal( - { - contentType: 'application/json', - action: 'request', - method: 'POST', - url: 'http://foo.com', - data: { name: 'John Doe', age: 30 }, - }, - metadataFixture - ) - const expected = factories.createNetworkSignal( - { - contentType: 'application/json', - action: 'request', - method: 'POST', - url: 'http://foo.com', - data: { name: 'XXX', age: 999 }, - }, - metadataFixture - ) + const signal = factories.createNetworkSignal({ + requestId: 'foo', + contentType: 'application/json', + action: 'request', + method: 'POST', + url: 'http://foo.com', + body: { name: 'John Doe', age: 30 }, + }) + const expected = factories.createNetworkSignal({ + requestId: 'foo', + contentType: 'application/json', + action: 'request', + method: 'POST', + url: 'http://foo.com', + body: { name: 'XXX', age: 999 }, + }) expect(redactSignalData(signal)).toMatchSignal(expected) }) diff --git a/packages/signals/signals/src/core/middleware/signals-ingest/redact.ts b/packages/signals/signals/src/core/middleware/signals-ingest/redact.ts index b7f888419..fc782799e 100644 --- a/packages/signals/signals/src/core/middleware/signals-ingest/redact.ts +++ b/packages/signals/signals/src/core/middleware/signals-ingest/redact.ts @@ -72,7 +72,7 @@ export const redactSignalData = (signalArg: Signal): Signal => { } } } else if (signal.type === 'network') { - signal.data.data = redactJsonValues(signal.data.data) + signal.data.body = redactJsonValues(signal.data.body) } return signal } diff --git a/packages/signals/signals/src/core/middleware/signals-ingest/signals-ingest-client.ts b/packages/signals/signals/src/core/middleware/signals-ingest/signals-ingest-client.ts index ae35aafc8..2373feb65 100644 --- a/packages/signals/signals/src/core/middleware/signals-ingest/signals-ingest-client.ts +++ b/packages/signals/signals/src/core/middleware/signals-ingest/signals-ingest-client.ts @@ -84,8 +84,8 @@ export class SignalsIngestClient { const MAGIC_EVENT_NAME = 'Segment Signal Generated' return analytics.track(MAGIC_EVENT_NAME, { - index: this.index++, ...cleanSignal, + index: this.index++, }) } diff --git a/packages/signals/signals/src/core/processor/sandbox.ts b/packages/signals/signals/src/core/processor/sandbox.ts index 78c9b3e3f..957790cbf 100644 --- a/packages/signals/signals/src/core/processor/sandbox.ts +++ b/packages/signals/signals/src/core/processor/sandbox.ts @@ -3,11 +3,7 @@ import { createWorkerBox, WorkerBoxAPI } from '../../lib/workerbox' import { resolvers } from './arg-resolvers' import { AnalyticsRuntimePublicApi, ProcessSignal } from '../../types' import { replaceBaseUrl } from '../../lib/replace-base-url' -import { - Signal, - WebRuntimeConstants, - WebSignalsRuntime, -} from '@segment/analytics-signals-runtime' +import { Signal, WebSignalsRuntime } from '@segment/analytics-signals-runtime' import { getRuntimeCode } from '@segment/analytics-signals-runtime' import { polyfills } from './polyfills' import { loadScript } from '../../lib/load-script' @@ -251,7 +247,7 @@ export class WorkerSandbox implements SignalSandbox { `signals.signalBuffer = ${JSON.stringify(signals)};`, 'try { processSignal(' + JSON.stringify(signal) + - ', { analytics, signals, SignalType, EventType, NavigationAction }); } catch(err) { console.error("Process signal failed.", err); }', + ', { analytics, signals }); } catch(err) { console.error("Process signal failed.", err); }', ].join('\n') await this.jsSandbox.run(code, scope) @@ -277,11 +273,6 @@ const processWithGlobalScopeExecutionEnv = ( return undefined } - // Load all constants into the global scope - Object.entries(WebRuntimeConstants).forEach(([key, value]) => { - g[key] = value - }) - // processSignal expects a global called `signals` -- of course, there can local variable naming conflict on the client, which is why globals were a bad idea. const analytics = new AnalyticsRuntime() const signals = new WebSignalsRuntime(signalBuffer) @@ -303,9 +294,6 @@ const processWithGlobalScopeExecutionEnv = ( analytics: analytics, signals: signals, // constants - EventType: WebRuntimeConstants.EventType, - NavigationAction: WebRuntimeConstants.NavigationAction, - SignalType: WebRuntimeConstants.SignalType, }) } finally { // restore globals diff --git a/packages/signals/signals/src/core/signal-generators/dom-gen/__tests__/change-gen.test.ts b/packages/signals/signals/src/core/signal-generators/dom-gen/__tests__/change-gen.test.ts index 3e777fb7f..d6f74e9ce 100644 --- a/packages/signals/signals/src/core/signal-generators/dom-gen/__tests__/change-gen.test.ts +++ b/packages/signals/signals/src/core/signal-generators/dom-gen/__tests__/change-gen.test.ts @@ -31,6 +31,13 @@ describe(OnChangeGenerator, () => { expect(emitSpy.mock.calls[0][0]).toMatchInlineSnapshot(` { "anonymousId": "", + "context": { + "library": { + "name": "@segment/analytics-next", + "version": "0.0.0", + }, + "signalsRuntime": "", + }, "data": { "change": { "value": "new value", @@ -66,6 +73,7 @@ describe(OnChangeGenerator, () => { "value": "new value", }, }, + "index": undefined, "timestamp": , "type": "interaction", } @@ -123,6 +131,13 @@ describe(OnChangeGenerator, () => { [ { "anonymousId": "", + "context": { + "library": { + "name": "@segment/analytics-next", + "version": "0.0.0", + }, + "signalsRuntime": "", + }, "data": { "change": { "selectedOptions": [ @@ -167,6 +182,7 @@ describe(OnChangeGenerator, () => { "value": "value1", }, }, + "index": undefined, "timestamp": , "type": "interaction", }, diff --git a/packages/signals/signals/src/core/signal-generators/dom-gen/__tests__/navigation-gen.test.ts b/packages/signals/signals/src/core/signal-generators/dom-gen/__tests__/navigation-gen.test.ts index 4f1fd64d5..d29066128 100644 --- a/packages/signals/signals/src/core/signal-generators/dom-gen/__tests__/navigation-gen.test.ts +++ b/packages/signals/signals/src/core/signal-generators/dom-gen/__tests__/navigation-gen.test.ts @@ -29,8 +29,15 @@ describe(OnNavigationEventGenerator, () => { [ { "anonymousId": "", + "context": { + "library": { + "name": "@segment/analytics-next", + "version": "0.0.0", + }, + "signalsRuntime": "", + }, "data": { - "action": "pageLoad", + "currentUrl": "http://localhost/", "hash": "", "page": { "hash": "", @@ -44,8 +51,8 @@ describe(OnNavigationEventGenerator, () => { "path": "/", "search": "", "title": "", - "url": "http://localhost/", }, + "index": undefined, "timestamp": , "type": "navigation", }, @@ -79,13 +86,20 @@ describe(OnNavigationEventGenerator, () => { [ { "anonymousId": "", + "context": { + "library": { + "name": "@segment/analytics-next", + "version": "0.0.0", + }, + "signalsRuntime": "", + }, "data": { - "action": "urlChange", "changedProperties": [ "path", "search", "hash", ], + "currentUrl": "http://localhost/new-path?query=123#hello", "hash": "#hello", "page": { "hash": "#hello", @@ -97,11 +111,11 @@ describe(OnNavigationEventGenerator, () => { "url": "http://localhost/new-path?query=123#hello", }, "path": "/new-path", - "prevUrl": "http://localhost/", + "previousUrl": "http://localhost/", "search": "?query=123", "title": "", - "url": "http://localhost/new-path?query=123#hello", }, + "index": undefined, "timestamp": , "type": "navigation", }, diff --git a/packages/signals/signals/src/core/signal-generators/dom-gen/navigation-gen.ts b/packages/signals/signals/src/core/signal-generators/dom-gen/navigation-gen.ts index bd5b133ac..538492798 100644 --- a/packages/signals/signals/src/core/signal-generators/dom-gen/navigation-gen.ts +++ b/packages/signals/signals/src/core/signal-generators/dom-gen/navigation-gen.ts @@ -30,10 +30,8 @@ export class OnNavigationEventGenerator implements SignalGenerator { } register(emitter: SignalEmitter): () => void { - // emit navigation signal on page load emitter.emit( createNavigationSignal({ - action: 'pageLoad', ...this.createCommonFields(), }) ) @@ -42,8 +40,7 @@ export class OnNavigationEventGenerator implements SignalGenerator { this.urlChange.subscribe(({ previous, current }) => emitter.emit( createNavigationSignal({ - action: 'urlChange', - prevUrl: previous.href, + previousUrl: previous.href, changedProperties: getChangedProperties(current, previous), ...this.createCommonFields(), }) @@ -58,7 +55,7 @@ export class OnNavigationEventGenerator implements SignalGenerator { private createCommonFields() { return { // these fields are named after those from the page call, rather than a DOM api. - url: location.href, + currentUrl: location.href, path: location.pathname, hash: location.hash, search: location.search, diff --git a/packages/signals/signals/src/core/signal-generators/network-gen/__tests__/network-generator.test.ts b/packages/signals/signals/src/core/signal-generators/network-gen/__tests__/network-generator.test.ts index f9f3acad0..ee3a27bef 100644 --- a/packages/signals/signals/src/core/signal-generators/network-gen/__tests__/network-generator.test.ts +++ b/packages/signals/signals/src/core/signal-generators/network-gen/__tests__/network-generator.test.ts @@ -98,12 +98,19 @@ describe(NetworkGenerator, () => { expect(first[0]).toMatchInlineSnapshot(` { "anonymousId": "", + "context": { + "library": { + "name": "@segment/analytics-next", + "version": "0.0.0", + }, + "signalsRuntime": "", + }, "data": { "action": "request", - "contentType": "application/json", - "data": { + "body": { "key": "value", }, + "contentType": "application/json", "method": "POST", "page": { "hash": "", @@ -114,14 +121,10 @@ describe(NetworkGenerator, () => { "title": "", "url": "http://localhost/", }, + "requestId": "cetsvycymt", "url": "http://localhost/test", }, - "metadata": { - "filters": { - "allowed": [], - "disallowed": [], - }, - }, + "index": undefined, "timestamp": , "type": "network", } @@ -130,12 +133,19 @@ describe(NetworkGenerator, () => { expect(second[0]).toMatchInlineSnapshot(` { "anonymousId": "", + "context": { + "library": { + "name": "@segment/analytics-next", + "version": "0.0.0", + }, + "signalsRuntime": "", + }, "data": { "action": "response", - "contentType": "application/json", - "data": { + "body": { "data": "test", }, + "contentType": "application/json", "ok": true, "page": { "hash": "", @@ -146,15 +156,11 @@ describe(NetworkGenerator, () => { "title": "", "url": "http://localhost/", }, + "requestId": "cetsvycymt", "status": 200, "url": "http://localhost/test", }, - "metadata": { - "filters": { - "allowed": [], - "disallowed": [], - }, - }, + "index": undefined, "timestamp": , "type": "network", } diff --git a/packages/signals/signals/src/core/signal-generators/network-gen/index.ts b/packages/signals/signals/src/core/signal-generators/network-gen/index.ts index 2b4051204..fded69bf9 100644 --- a/packages/signals/signals/src/core/signal-generators/network-gen/index.ts +++ b/packages/signals/signals/src/core/signal-generators/network-gen/index.ts @@ -22,7 +22,7 @@ export class NetworkGenerator implements SignalGenerator { return } - const data = typeof rq.body === 'string' ? tryJSONParse(rq.body) : null + const body = typeof rq.body === 'string' ? tryJSONParse(rq.body) : null this.emittedRequestIds.push(rq.id) emitter.emit( @@ -30,8 +30,9 @@ export class NetworkGenerator implements SignalGenerator { action: 'request', url: rq.url, method: rq.method || 'GET', - data, + body, contentType: rq.headers?.get('content-type') || '', + requestId: rq.id, }) ) } @@ -59,10 +60,11 @@ export class NetworkGenerator implements SignalGenerator { createNetworkSignal({ action: 'response', url, - data: data, + body: data, ok: rs.ok, status: rs.status, contentType: rs.headers.get('content-type') || '', + requestId: rs.req.id, }) ) } diff --git a/packages/signals/signals/src/types/__tests__/create-network-signal.test.ts b/packages/signals/signals/src/types/__tests__/create-network-signal.test.ts index 2245eee62..60d2ba832 100644 --- a/packages/signals/signals/src/types/__tests__/create-network-signal.test.ts +++ b/packages/signals/signals/src/types/__tests__/create-network-signal.test.ts @@ -1,7 +1,4 @@ -import { - NetworkData, - NetworkSignalMetadata, -} from '@segment/analytics-signals-runtime' +import { NetworkData } from '@segment/analytics-signals-runtime' import { normalizeUrl } from '../../lib/normalize-url' import { createNetworkSignal } from '../factories' @@ -10,32 +7,34 @@ jest.mock('../../lib/normalize-url', () => ({ })) describe(createNetworkSignal, () => { - const metadata: NetworkSignalMetadata = { - filters: { - allowed: ['allowed1', 'allowed2'], - disallowed: ['disallowed1', 'disallowed2'], - }, - } it('should create a network signal for a request', () => { - const data: NetworkData = { + const body: NetworkData = { action: 'request', url: 'http://example.com', method: 'POST', - data: { key: 'value' }, + body: { key: 'value' }, contentType: 'application/json', + requestId: '12345', } - const signal = createNetworkSignal(data, metadata) + const signal = createNetworkSignal(body) expect(signal).toMatchInlineSnapshot(` { "anonymousId": "", + "context": { + "library": { + "name": "@segment/analytics-next", + "version": "0.0.0", + }, + "signalsRuntime": "", + }, "data": { "action": "request", - "contentType": "application/json", - "data": { + "body": { "key": "value", }, + "contentType": "application/json", "method": "POST", "page": { "hash": "", @@ -46,20 +45,10 @@ describe(createNetworkSignal, () => { "title": "", "url": "http://localhost/", }, + "requestId": "12345", "url": "http://example.com", }, - "metadata": { - "filters": { - "allowed": [ - "allowed1", - "allowed2", - ], - "disallowed": [ - "disallowed1", - "disallowed2", - ], - }, - }, + "index": undefined, "timestamp": , "type": "network", } @@ -68,26 +57,34 @@ describe(createNetworkSignal, () => { }) it('should create a network signal for a response', () => { - const data: NetworkData = { + const body: NetworkData = { action: 'response', + requestId: '12345', url: 'http://example.com', ok: true, status: 200, contentType: 'application/json', - data: { key: 'value' }, + body: { key: 'value' }, } - const signal = createNetworkSignal(data, metadata) + const signal = createNetworkSignal(body) expect(signal).toMatchInlineSnapshot(` { "anonymousId": "", + "context": { + "library": { + "name": "@segment/analytics-next", + "version": "0.0.0", + }, + "signalsRuntime": "", + }, "data": { "action": "response", - "contentType": "application/json", - "data": { + "body": { "key": "value", }, + "contentType": "application/json", "ok": true, "page": { "hash": "", @@ -98,21 +95,11 @@ describe(createNetworkSignal, () => { "title": "", "url": "http://localhost/", }, + "requestId": "12345", "status": 200, "url": "http://example.com", }, - "metadata": { - "filters": { - "allowed": [ - "allowed1", - "allowed2", - ], - "disallowed": [ - "disallowed1", - "disallowed2", - ], - }, - }, + "index": undefined, "timestamp": , "type": "network", } diff --git a/packages/signals/signals/src/types/factories.ts b/packages/signals/signals/src/types/factories.ts index 4e6be2d70..45b72aaaf 100644 --- a/packages/signals/signals/src/types/factories.ts +++ b/packages/signals/signals/src/types/factories.ts @@ -4,20 +4,20 @@ import { UserDefinedSignalData, UserDefinedSignal, NetworkData, - NetworkSignalMetadata, NetworkSignal, - SignalTypes, + SignalType, Signal, SignalOfType, InstrumentationSignal, InteractionData, InteractionSignal, SegmentEvent, + EventType, } from '@segment/analytics-signals-runtime' import { normalizeUrl } from '../lib/normalize-url' import { getPageData } from '../lib/page-data' -type BaseData = Omit< +type BaseData = Omit< SignalOfType['data'], 'page' > @@ -25,17 +25,22 @@ type BaseData = Omit< /** * Base Signal Factory */ -const createBaseSignal = < - Type extends SignalTypes, - Data extends BaseData ->( +const createBaseSignal = >( type: Type, data: Data ) => { return { + index: undefined, // This will get overridden by a middleware that runs once analytics is instantiated timestamp: new Date().toISOString(), anonymousId: '', // to be set by a middleware (that runs once analytics is instantiated) type, + context: { + library: { + name: '@segment/analytics-next', + version: '0.0.0', + }, + signalsRuntime: '', + }, data: { ...data, page: getPageData(), @@ -46,7 +51,10 @@ const createBaseSignal = < export const createInstrumentationSignal = ( rawEvent: SegmentEvent ): InstrumentationSignal => { - return createBaseSignal('instrumentation', { rawEvent }) + return createBaseSignal('instrumentation', { + rawEvent, + type: rawEvent.type as EventType, + }) } export const createInteractionSignal = ( @@ -67,20 +75,11 @@ export const createUserDefinedSignal = ( return createBaseSignal('userDefined', data) } -export const createNetworkSignal = ( - data: NetworkData, - metadata?: NetworkSignalMetadata -): NetworkSignal => { +export const createNetworkSignal = (data: NetworkData): NetworkSignal => { return { ...createBaseSignal('network', { ...data, url: normalizeUrl(data.url), }), - metadata: metadata ?? { - filters: { - allowed: [], - disallowed: [], - }, - }, } } diff --git a/packages/signals/signals/src/types/process-signal.ts b/packages/signals/signals/src/types/process-signal.ts index 0f8b2bfd8..60b551070 100644 --- a/packages/signals/signals/src/types/process-signal.ts +++ b/packages/signals/signals/src/types/process-signal.ts @@ -1,8 +1,4 @@ -import { - Signal, - WebRuntimeConstants, - SignalsRuntime, -} from '@segment/analytics-signals-runtime' +import { Signal, SignalsRuntime } from '@segment/analytics-signals-runtime' /** * Types for the signals runtime @@ -20,7 +16,7 @@ export interface AnalyticsRuntimePublicApi { export type ProcessSignalScope = { analytics: AnalyticsRuntimePublicApi signals: SignalsRuntime -} & typeof WebRuntimeConstants +} export interface ProcessSignal { (signal: Signal, ctx: ProcessSignalScope): void diff --git a/yarn.lock b/yarn.lock index c2cfba2f4..e55df780a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6184,21 +6184,14 @@ __metadata: languageName: unknown linkType: soft -"@segment/analytics-signals-runtime@1.5.1, @segment/analytics-signals-runtime@workspace:packages/signals/signals-runtime": - version: 0.0.0-use.local - resolution: "@segment/analytics-signals-runtime@workspace:packages/signals/signals-runtime" +"@segment/analytics-signals-runtime@npm:2.0.0": + version: 2.0.0 + resolution: "@segment/analytics-signals-runtime@npm:2.0.0" dependencies: - "@babel/cli": ^7.22.10 - "@babel/core": ^7.22.11 - "@babel/preset-env": ^7.22.10 - "@babel/preset-typescript": ^7.22.11 - "@internal/test-helpers": "workspace:^" - "@microsoft/api-extractor": ^7.47.9 - babel-preset-minify: ^0.5.2 - esbuild-plugin-babel-cjs: ^1.0.0 tslib: ^2.4.1 - languageName: unknown - linkType: soft + checksum: 4df82a041bb66514de606b29866f59cf3ecac449766a649d9d4cb586e52183d5f3b866c3cb041774e259331c9fa38181325f1a5ab4528202cf86c3e9be03906f + languageName: node + linkType: hard "@segment/analytics-signals@workspace:^, @segment/analytics-signals@workspace:packages/signals/signals": version: 0.0.0-use.local @@ -6207,7 +6200,7 @@ __metadata: "@internal/config-webpack": "workspace:^" "@internal/test-helpers": "workspace:^" "@segment/analytics-generic-utils": 1.2.0 - "@segment/analytics-signals-runtime": 1.5.1 + "@segment/analytics-signals-runtime": 2.0.0 fake-indexeddb: ^6.0.0 idb: ^8.0.0 node-fetch: ^2.6.7 @@ -10240,55 +10233,6 @@ __metadata: languageName: node linkType: hard -"babel-helper-evaluate-path@npm:^0.5.0": - version: 0.5.0 - resolution: "babel-helper-evaluate-path@npm:0.5.0" - checksum: 4a3b301fd931e0cd3f9ec2a34b4c29a32d31acb6465d2b29793d2b27207bcd50e8e06dd9d95e4a91171d0da82c971404ed9e6aed586a3f2c4b09243cd531fb2a - languageName: node - linkType: hard - -"babel-helper-flip-expressions@npm:^0.4.3": - version: 0.4.3 - resolution: "babel-helper-flip-expressions@npm:0.4.3" - checksum: 52174b03edfca1c722b115fae7046d3ddfd726d2e240cb018c6877b1b9baef7a07f9853ed33a37ee7eeebb5769b1748a0cffbd303f9b5a454e18420e0f0a859b - languageName: node - linkType: hard - -"babel-helper-is-nodes-equiv@npm:^0.0.1": - version: 0.0.1 - resolution: "babel-helper-is-nodes-equiv@npm:0.0.1" - checksum: 8621bf12fe5e8238c2de125be278e57f02233fa0e0cf59e0f6b8218b9699eac7a3f71087c8fac5981a80d0941382b34794c642cbbffe363286ac49601b4584ef - languageName: node - linkType: hard - -"babel-helper-is-void-0@npm:^0.4.3": - version: 0.4.3 - resolution: "babel-helper-is-void-0@npm:0.4.3" - checksum: 0aa68c822c21b3688161d9748b83cc25062a1d4ea39c342c17c7f59d33993de476338d01a3b6218d99f725287be03638d3119d5fe774319eb87054e04e06cf43 - languageName: node - linkType: hard - -"babel-helper-mark-eval-scopes@npm:^0.4.3": - version: 0.4.3 - resolution: "babel-helper-mark-eval-scopes@npm:0.4.3" - checksum: 3cf6a1b5ab4e519242abf0031b96bd86ef2ad614a2b296231b6b4480f6f998b84ba99a629426b5c6b00e598c10b8ba2af6d2e9d1c7c3c94ed4a2bc9082f71c33 - languageName: node - linkType: hard - -"babel-helper-remove-or-void@npm:^0.4.3": - version: 0.4.3 - resolution: "babel-helper-remove-or-void@npm:0.4.3" - checksum: 6a2c305c31cb0974a2fd6c860a6685612b4a7ad2cd6b056807f183d9ef5c86f669c002f454fe6729bfd594e5f7349b1f7f06b2107acd7e353e1ccfb2e4d8f32e - languageName: node - linkType: hard - -"babel-helper-to-multiple-sequence-expressions@npm:^0.5.0": - version: 0.5.0 - resolution: "babel-helper-to-multiple-sequence-expressions@npm:0.5.0" - checksum: f8f07139eefc87b3e3f7733250b638cb61e03567060bded12934f48800ec07e86a304815e49a4b83610b549234aeb9db9ff1dc71a7bde1442d37e9ebed658ba0 - languageName: node - linkType: hard - "babel-jest@npm:^29.7.0": version: 29.7.0 resolution: "babel-jest@npm:29.7.0" @@ -10346,104 +10290,6 @@ __metadata: languageName: node linkType: hard -"babel-plugin-minify-builtins@npm:^0.5.0": - version: 0.5.0 - resolution: "babel-plugin-minify-builtins@npm:0.5.0" - checksum: 55fa4b2e77bb5d8e5008e4ab8a5435d5edd64796388840fdff28cb9d67aa4c4a5a075a9b9253672b8d1e683fd3a58cf7085e6151eea05d5737a7ab364053b68c - languageName: node - linkType: hard - -"babel-plugin-minify-constant-folding@npm:^0.5.0": - version: 0.5.0 - resolution: "babel-plugin-minify-constant-folding@npm:0.5.0" - dependencies: - babel-helper-evaluate-path: ^0.5.0 - checksum: 9421a07cf29213852c6f284f16cc9159acfe06df747addc42e3b2dec624bd70bd0af2f18c180e7bdeba40cc63910b99297fb8ecc59da56059847ab5d073dfcb2 - languageName: node - linkType: hard - -"babel-plugin-minify-dead-code-elimination@npm:^0.5.2": - version: 0.5.2 - resolution: "babel-plugin-minify-dead-code-elimination@npm:0.5.2" - dependencies: - babel-helper-evaluate-path: ^0.5.0 - babel-helper-mark-eval-scopes: ^0.4.3 - babel-helper-remove-or-void: ^0.4.3 - lodash: ^4.17.11 - checksum: ed4c683aa9dac021f08bf46a9a8dae28428e32e0beb0cb0e1923e195490019c5169c42e8211ecc9e23c9e2ce6ac54a809af7b9f9d8cece57eebb51b07b9f2e64 - languageName: node - linkType: hard - -"babel-plugin-minify-flip-comparisons@npm:^0.4.3": - version: 0.4.3 - resolution: "babel-plugin-minify-flip-comparisons@npm:0.4.3" - dependencies: - babel-helper-is-void-0: ^0.4.3 - checksum: 54e068f926083d6ae539a13d096a9fa564339717ee607f9b3bded360344d377fa6dd47ada377ac445f98462d03d78cdf772efcaa366c692888f325c6382ab6a6 - languageName: node - linkType: hard - -"babel-plugin-minify-guarded-expressions@npm:^0.4.4": - version: 0.4.4 - resolution: "babel-plugin-minify-guarded-expressions@npm:0.4.4" - dependencies: - babel-helper-evaluate-path: ^0.5.0 - babel-helper-flip-expressions: ^0.4.3 - checksum: 6071558a5bdc64ed811809d66ad9982ea3ead16ac32f09d4f17e41b07b2106d9b0d12641758f89cfa1dff94fdfb3df8afed908ff1c0e50972b0312cc66d09a75 - languageName: node - linkType: hard - -"babel-plugin-minify-infinity@npm:^0.4.3": - version: 0.4.3 - resolution: "babel-plugin-minify-infinity@npm:0.4.3" - checksum: d63d83390286949043adf43016150a46d8d7b4d500cdd684a24322d2ec9153127af0c2df36debe3096e12eff3712d4974935585953d0337a09966f0ec5c81f84 - languageName: node - linkType: hard - -"babel-plugin-minify-mangle-names@npm:^0.5.1": - version: 0.5.1 - resolution: "babel-plugin-minify-mangle-names@npm:0.5.1" - dependencies: - babel-helper-mark-eval-scopes: ^0.4.3 - checksum: fd4dcf6d20b68130063c2e44ebf7c5fa4e912be6bfc8d9036697ac087a348ce2c289aab8d04a3905228e40a3c966300dc0c8e58cc53a16d97553637d820f0669 - languageName: node - linkType: hard - -"babel-plugin-minify-numeric-literals@npm:^0.4.3": - version: 0.4.3 - resolution: "babel-plugin-minify-numeric-literals@npm:0.4.3" - checksum: 8327b43e06ead88c13558ecaa5faf32bbca0e3f726fce93b59bac92d423291abbe6912419ba4b9f669253318cdf04381c5d6d6eabacaafd51a69c9242975dc5b - languageName: node - linkType: hard - -"babel-plugin-minify-replace@npm:^0.5.0": - version: 0.5.0 - resolution: "babel-plugin-minify-replace@npm:0.5.0" - checksum: eca0ef9c9197b55b7c6467fb097fe3f266ca64293eda0c1254303897923df11e9f5a9c25888de98da6a4fc32debe2651d50bdcebb667553013be4875543480f6 - languageName: node - linkType: hard - -"babel-plugin-minify-simplify@npm:^0.5.1": - version: 0.5.1 - resolution: "babel-plugin-minify-simplify@npm:0.5.1" - dependencies: - babel-helper-evaluate-path: ^0.5.0 - babel-helper-flip-expressions: ^0.4.3 - babel-helper-is-nodes-equiv: ^0.0.1 - babel-helper-to-multiple-sequence-expressions: ^0.5.0 - checksum: 79d718001337fc93f7b6002f2940dbbe35b0704b75e2c0c408eae88ac81400af7a2a79e3c7fcbfb781fd00466a45fd1fff94040cad811002992930e9e26cc1fa - languageName: node - linkType: hard - -"babel-plugin-minify-type-constructors@npm:^0.4.3": - version: 0.4.3 - resolution: "babel-plugin-minify-type-constructors@npm:0.4.3" - dependencies: - babel-helper-is-void-0: ^0.4.3 - checksum: 2c6cb97aa8a20c990fc17afd1141e586a1920419bc8a93d2231e7f5f6dcdfbc060c1839873c192c7828040f95ff74b65b8b0af6eb5c54b795e86cf62152ba41e - languageName: node - linkType: hard - "babel-plugin-polyfill-corejs2@npm:^0.4.5": version: 0.4.5 resolution: "babel-plugin-polyfill-corejs2@npm:0.4.5" @@ -10480,87 +10326,6 @@ __metadata: languageName: node linkType: hard -"babel-plugin-transform-inline-consecutive-adds@npm:^0.4.3": - version: 0.4.3 - resolution: "babel-plugin-transform-inline-consecutive-adds@npm:0.4.3" - checksum: e3129bafc9c0ac8b0f3f823db3121d66d03c882fe78c1a0ab0ba5da45889759b7f9176a1b243c0eda12e27353bfd27934ef56e6a3f65861894b78dce96e3df35 - languageName: node - linkType: hard - -"babel-plugin-transform-member-expression-literals@npm:^6.9.4": - version: 6.9.4 - resolution: "babel-plugin-transform-member-expression-literals@npm:6.9.4" - checksum: 0008ca6f50dbeb7642422ed2c8024a05adc3cb9cad89993e7e1f1fa9bf085574bd874e853857fe441aff4b52ff2c1d7ea273c89da0ca6711a43de317ecf35cfb - languageName: node - linkType: hard - -"babel-plugin-transform-merge-sibling-variables@npm:^6.9.5": - version: 6.9.5 - resolution: "babel-plugin-transform-merge-sibling-variables@npm:6.9.5" - checksum: 6182f79703170b473fe4872cfe0df144057d94632be9972076265d3aae05e37aab3fb98ed932ce6d663c722d9aabb48ee2046b2f820ccc73dc45260173ba36e2 - languageName: node - linkType: hard - -"babel-plugin-transform-minify-booleans@npm:^6.9.4": - version: 6.9.4 - resolution: "babel-plugin-transform-minify-booleans@npm:6.9.4" - checksum: d8553742aa5ddfbcbc9c34c05bf4dce1148026b6aa860b3f1d0f7c8820f8d88e21dca148387c1ddf1e94b5fa7d7f39476bc8c07f082639aee2b841d8df5afc4c - languageName: node - linkType: hard - -"babel-plugin-transform-property-literals@npm:^6.9.4": - version: 6.9.4 - resolution: "babel-plugin-transform-property-literals@npm:6.9.4" - dependencies: - esutils: ^2.0.2 - checksum: 14da12703c8b49841594670688c50dc2f7b2be88b5681c70311f5f88b27a50782747a04e9fe1b232b7d2c2a9f223228c61fe6fe41ae0c4eb8208e3a890b2a19d - languageName: node - linkType: hard - -"babel-plugin-transform-regexp-constructors@npm:^0.4.3": - version: 0.4.3 - resolution: "babel-plugin-transform-regexp-constructors@npm:0.4.3" - checksum: 242228775b2c9e7d147a3bc3f8e0ce5d903f3baf7b238edc6c4fe4d95d05f84cc4722f37598cae437c26ffc24d63262550abb79d28eefe3c34d98b36be6d4f17 - languageName: node - linkType: hard - -"babel-plugin-transform-remove-console@npm:^6.9.4": - version: 6.9.4 - resolution: "babel-plugin-transform-remove-console@npm:6.9.4" - checksum: 1123c3816c6f89c064752199c8796f30265d937f5d8e1e43d3837f1c0e87ed0e6bbd0afa6117ce021c8b93ec1de7154e158674bb22331c7ed6609d10121359df - languageName: node - linkType: hard - -"babel-plugin-transform-remove-debugger@npm:^6.9.4": - version: 6.9.4 - resolution: "babel-plugin-transform-remove-debugger@npm:6.9.4" - checksum: ed34e5200dcd6e3f954debb3547baa58c8e422e084984a7d66cac4789bee158424c2d4ab21e0bac25e6818316d9c8ca758a976cf20ac333073146089eae6d49c - languageName: node - linkType: hard - -"babel-plugin-transform-remove-undefined@npm:^0.5.0": - version: 0.5.0 - resolution: "babel-plugin-transform-remove-undefined@npm:0.5.0" - dependencies: - babel-helper-evaluate-path: ^0.5.0 - checksum: cebba3eae74decba944af78bdbd1e806461bed8a3d500c4bc26dc563d5f1af087d5347f9ac1a3f28cc0ed9186a4095ced0f0099d5ec7aa6cf7ef2119436cafe4 - languageName: node - linkType: hard - -"babel-plugin-transform-simplify-comparison-operators@npm:^6.9.4": - version: 6.9.4 - resolution: "babel-plugin-transform-simplify-comparison-operators@npm:6.9.4" - checksum: 0b51e361d4c8c7a5b8813a4d652232c3185c3a17c0f0529676f706da876be1432a5bfc3a418fb801e266db67f12f2b92d4bef93a1c5f4582a3cb4edd2de457c2 - languageName: node - linkType: hard - -"babel-plugin-transform-undefined-to-void@npm:^6.9.4": - version: 6.9.4 - resolution: "babel-plugin-transform-undefined-to-void@npm:6.9.4" - checksum: dd4d89b3e884ed0a35c0a0690fdfa4cf9d5a1678b796a20bc05467f68fc5e186c5f77bc127870811337deb989afed6f6775fb8eab94646fcc7ed1a454c455a95 - languageName: node - linkType: hard - "babel-preset-current-node-syntax@npm:^1.0.0": version: 1.0.1 resolution: "babel-preset-current-node-syntax@npm:1.0.1" @@ -10595,37 +10360,6 @@ __metadata: languageName: node linkType: hard -"babel-preset-minify@npm:^0.5.2": - version: 0.5.2 - resolution: "babel-preset-minify@npm:0.5.2" - dependencies: - babel-plugin-minify-builtins: ^0.5.0 - babel-plugin-minify-constant-folding: ^0.5.0 - babel-plugin-minify-dead-code-elimination: ^0.5.2 - babel-plugin-minify-flip-comparisons: ^0.4.3 - babel-plugin-minify-guarded-expressions: ^0.4.4 - babel-plugin-minify-infinity: ^0.4.3 - babel-plugin-minify-mangle-names: ^0.5.1 - babel-plugin-minify-numeric-literals: ^0.4.3 - babel-plugin-minify-replace: ^0.5.0 - babel-plugin-minify-simplify: ^0.5.1 - babel-plugin-minify-type-constructors: ^0.4.3 - babel-plugin-transform-inline-consecutive-adds: ^0.4.3 - babel-plugin-transform-member-expression-literals: ^6.9.4 - babel-plugin-transform-merge-sibling-variables: ^6.9.5 - babel-plugin-transform-minify-booleans: ^6.9.4 - babel-plugin-transform-property-literals: ^6.9.4 - babel-plugin-transform-regexp-constructors: ^0.4.3 - babel-plugin-transform-remove-console: ^6.9.4 - babel-plugin-transform-remove-debugger: ^6.9.4 - babel-plugin-transform-remove-undefined: ^0.5.0 - babel-plugin-transform-simplify-comparison-operators: ^6.9.4 - babel-plugin-transform-undefined-to-void: ^6.9.4 - lodash: ^4.17.11 - checksum: 36484ad5d4cf89948240ad99ee3eb8bc54c85aed9c5d47b188924dfea058157a7e66a6980624f34c8ec45fc2906161f7ae0cbd3017f983a71689b29f79bebc90 - languageName: node - linkType: hard - "balanced-match@npm:^1.0.0": version: 1.0.2 resolution: "balanced-match@npm:1.0.2" @@ -13173,15 +12907,6 @@ __metadata: languageName: node linkType: hard -"esbuild-plugin-babel-cjs@npm:^1.0.0": - version: 1.0.0 - resolution: "esbuild-plugin-babel-cjs@npm:1.0.0" - peerDependencies: - "@babel/core": ^7.0.0 - checksum: d2a766a93fcb488868bdc30f2247c02c70d40cdd7785e7195f19235e2a3aeb569f6c574ca1629f585500584057e66bbf43b7c6a216f354667cec6633c668477f - languageName: node - linkType: hard - "esbuild-sunos-64@npm:0.14.54": version: 0.14.54 resolution: "esbuild-sunos-64@npm:0.14.54" @@ -17756,7 +17481,7 @@ __metadata: languageName: node linkType: hard -"lodash@npm:^4.17.11, lodash@npm:^4.17.14, lodash@npm:^4.17.19, lodash@npm:^4.17.20, lodash@npm:^4.17.21, lodash@npm:~4.17.15": +"lodash@npm:^4.17.14, lodash@npm:^4.17.19, lodash@npm:^4.17.20, lodash@npm:^4.17.21, lodash@npm:~4.17.15": version: 4.17.21 resolution: "lodash@npm:4.17.21" checksum: eb835a2e51d381e561e508ce932ea50a8e5a68f4ebdd771ea240d3048244a8d13658acbd502cd4829768c56f2e16bdd4340b9ea141297d472517b83868e677f7 From 785242d39bf6da42b57edc6684389b7fbfedf0e9 Mon Sep 17 00:00:00 2001 From: Seth Silesky <5115498+silesky@users.noreply.github.com> Date: Wed, 9 Jul 2025 16:50:48 -0500 Subject: [PATCH 2/5] update package to use new spec --- .changeset/thick-cars-compete.md | 5 ++++ .../all-segment-events.test.ts | 2 +- .../src/tests/signals-vanilla/basic.test.ts | 8 +++--- .../network-signals-fetch.test.ts | 25 +++++++++++-------- .../network-signals-xhr.test.ts | 24 +++++++++--------- 5 files changed, 35 insertions(+), 29 deletions(-) create mode 100644 .changeset/thick-cars-compete.md diff --git a/.changeset/thick-cars-compete.md b/.changeset/thick-cars-compete.md new file mode 100644 index 000000000..b60d91d05 --- /dev/null +++ b/.changeset/thick-cars-compete.md @@ -0,0 +1,5 @@ +--- +'@segment/analytics-signals': major +--- + +Update package to use new spec diff --git a/packages/signals/signals-integration-tests/src/tests/signals-vanilla/all-segment-events.test.ts b/packages/signals/signals-integration-tests/src/tests/signals-vanilla/all-segment-events.test.ts index 58b3cafdf..188cdaf28 100644 --- a/packages/signals/signals-integration-tests/src/tests/signals-vanilla/all-segment-events.test.ts +++ b/packages/signals/signals-integration-tests/src/tests/signals-vanilla/all-segment-events.test.ts @@ -66,7 +66,7 @@ test('Should dispatch events from signals that occurred before analytics was ins }) => { const edgeFn = ` globalThis.processSignal = (signal) => { - if (signal.type === 'navigation' && signal.data.action === 'pageLoad') { + if (signal.type === 'navigation') { analytics.page('dispatched from signals - navigation') } if (signal.type === 'userDefined') { diff --git a/packages/signals/signals-integration-tests/src/tests/signals-vanilla/basic.test.ts b/packages/signals/signals-integration-tests/src/tests/signals-vanilla/basic.test.ts index 4317d1f33..45cb006ec 100644 --- a/packages/signals/signals-integration-tests/src/tests/signals-vanilla/basic.test.ts +++ b/packages/signals/signals-integration-tests/src/tests/signals-vanilla/basic.test.ts @@ -155,8 +155,7 @@ test('navigation signals', async ({ page }) => { expect(ev.properties).toMatchObject({ type: 'navigation', data: { - action: 'pageLoad', - url: indexPage.url, + currentUrl: indexPage.url, path: expect.any(String), hash: '', search: '', @@ -178,9 +177,8 @@ test('navigation signals', async ({ page }) => { index: expect.any(Number), type: 'navigation', data: { - action: 'urlChange', - url: indexPage.url + '#foo', - prevUrl: indexPage.url, + currentUrl: indexPage.url + '#foo', + previousUrl: indexPage.url, path: expect.any(String), hash: '#foo', search: '', diff --git a/packages/signals/signals-integration-tests/src/tests/signals-vanilla/network-signals-fetch.test.ts b/packages/signals/signals-integration-tests/src/tests/signals-vanilla/network-signals-fetch.test.ts index 6d92d67bc..4f0a5d5bb 100644 --- a/packages/signals/signals-integration-tests/src/tests/signals-vanilla/network-signals-fetch.test.ts +++ b/packages/signals/signals-integration-tests/src/tests/signals-vanilla/network-signals-fetch.test.ts @@ -4,6 +4,8 @@ import { IndexPage } from './index-page' const basicEdgeFn = `globalThis.processSignal = (signal) => {}` +const NON_EMPTY_STRING = expect.stringMatching(/.+/) + test.describe('network signals - fetch', () => { let indexPage: IndexPage @@ -30,7 +32,6 @@ test.describe('network signals - fetch', () => { expect(requests[0].properties!.data).toMatchObject({ action: 'request', contentType: 'multipart/form-data', - data: null, method: 'POST', url: 'http://localhost/upload', ...commonSignalData, @@ -62,7 +63,7 @@ test.describe('network signals - fetch', () => { expect(requests[0].properties!.data).toMatchObject({ action: 'request', url: 'http://localhost/test', - data: { key: 'value' }, + body: { key: 'value' }, ...commonSignalData, }) }) @@ -92,7 +93,7 @@ test.describe('network signals - fetch', () => { expect(requests[0].properties!.data).toMatchObject({ action: 'request', url: 'http://localhost/test', - data: 'hello world', + body: 'hello world', ...commonSignalData, }) }) @@ -123,12 +124,13 @@ test.describe('network signals - fetch', () => { (el) => el.properties!.data.action === 'request' ) expect(requests).toHaveLength(1) - expect(requests[0].properties!.data).toEqual({ + expect(requests[0].properties!.data).toMatchObject({ action: 'request', contentType: 'application/json', url: 'http://localhost/test', method: 'POST', - data: { key: 'value' }, + body: { key: 'value' }, + requestId: NON_EMPTY_STRING, ...commonSignalData, }) @@ -136,13 +138,14 @@ test.describe('network signals - fetch', () => { (el) => el.properties!.data.action === 'response' ) expect(responses).toHaveLength(1) - expect(responses[0].properties!.data).toEqual({ + expect(responses[0].properties!.data).toMatchObject({ action: 'response', contentType: 'application/json', url: 'http://localhost/test', - data: { foo: 'test' }, + body: { foo: 'test' }, status: 200, ok: true, + requestId: NON_EMPTY_STRING, ...commonSignalData, }) }) @@ -171,7 +174,7 @@ test.describe('network signals - fetch', () => { expect(requests[0].properties!.data).toMatchObject({ action: 'request', url: `${indexPage.origin()}/test`, - data: { key: 'value' }, + body: { key: 'value' }, ...commonSignalData, }) @@ -182,7 +185,7 @@ test.describe('network signals - fetch', () => { expect(responses[0].properties!.data).toMatchObject({ action: 'response', url: `${indexPage.origin()}/test`, - data: { foo: 'test' }, + body: { foo: 'test' }, ...commonSignalData, }) }) @@ -220,7 +223,7 @@ test.describe('network signals - fetch', () => { expect(responses[0].properties!.data).toMatchObject({ action: 'response', url: 'http://localhost/test', - data: { errorMsg: 'foo' }, + body: { errorMsg: 'foo' }, status: 400, ok: false, page: expect.any(Object), @@ -260,7 +263,7 @@ test.describe('network signals - fetch', () => { expect(responses[0].properties!.data).toMatchObject({ action: 'response', url: 'http://localhost/test', - data: 'foo', + body: 'foo', status: 400, ok: false, ...commonSignalData, diff --git a/packages/signals/signals-integration-tests/src/tests/signals-vanilla/network-signals-xhr.test.ts b/packages/signals/signals-integration-tests/src/tests/signals-vanilla/network-signals-xhr.test.ts index 13729c583..c69fc7e18 100644 --- a/packages/signals/signals-integration-tests/src/tests/signals-vanilla/network-signals-xhr.test.ts +++ b/packages/signals/signals-integration-tests/src/tests/signals-vanilla/network-signals-xhr.test.ts @@ -34,7 +34,7 @@ test.describe('network signals - XHR', () => { expect(requests[0].properties!.data).toMatchObject({ action: 'request', url: 'http://localhost/test', - data: { key: 'value' }, + body: { key: 'value' }, }) // Check the response @@ -45,7 +45,7 @@ test.describe('network signals - XHR', () => { expect(responses[0].properties!.data).toMatchObject({ action: 'response', url: 'http://localhost/test', - data: { foo: 'test' }, + body: { foo: 'test' }, }) }) @@ -74,7 +74,7 @@ test.describe('network signals - XHR', () => { expect(requests[0].properties!.data).toMatchObject({ action: 'request', url: `${indexPage.origin()}/test`, - data: { key: 'value' }, + body: { key: 'value' }, }) // Check the response @@ -85,7 +85,7 @@ test.describe('network signals - XHR', () => { expect(responses[0].properties!.data).toMatchObject({ action: 'response', url: `${indexPage.origin()}/test`, - data: { foo: 'test' }, + body: { foo: 'test' }, }) }) @@ -114,7 +114,7 @@ test.describe('network signals - XHR', () => { expect(requests[0].properties!.data).toMatchObject({ action: 'request', url: 'http://localhost/test', - data: 'hello world', + body: 'hello world', }) // Check the response @@ -125,7 +125,7 @@ test.describe('network signals - XHR', () => { expect(responses[0].properties!.data).toMatchObject({ action: 'response', url: 'http://localhost/test', - data: { foo: 'test' }, + body: { foo: 'test' }, }) }) @@ -153,7 +153,7 @@ test.describe('network signals - XHR', () => { expect(responses[0].properties!.data).toMatchObject({ action: 'response', url: 'http://localhost/test', - data: { hello: 'world' }, + body: { hello: 'world' }, }) }) @@ -200,7 +200,7 @@ test.describe('network signals - XHR', () => { expect(request1.properties!.data).toMatchObject({ action: 'request', url: req1URL, - data: { req1: 'value' }, + body: { req1: 'value' }, }) const request2 = requests.find((u) => u.properties!.data.url === req2URL)! @@ -208,7 +208,7 @@ test.describe('network signals - XHR', () => { expect(request2.properties!.data).toMatchObject({ action: 'request', url: req2URL, - data: { req2: 'value' }, + body: { req2: 'value' }, }) }) @@ -246,7 +246,7 @@ test.describe('network signals - XHR', () => { expect(responses[0].properties!.data).toMatchObject({ action: 'response', url: 'http://localhost/test', - data: { errorMsg: 'foo' }, + body: { errorMsg: 'foo' }, }) expect(responses).toHaveLength(1) }) @@ -284,7 +284,7 @@ test.describe('network signals - XHR', () => { expect(responses[0].properties!.data).toMatchObject({ action: 'response', url: 'http://localhost/test', - data: 'foo', + body: 'foo', }) expect(responses).toHaveLength(1) }) @@ -325,7 +325,7 @@ test.describe('network signals - XHR', () => { expect(responses[0].properties!.data).toMatchObject({ action: 'response', url: 'http://localhost/test', - data: null, + body: null, }) expect(responses).toHaveLength(1) }) From 8c5c897a93300e2df16687fb26a545c02d50d245 Mon Sep 17 00:00:00 2001 From: Seth Silesky <5115498+silesky@users.noreply.github.com> Date: Wed, 9 Jul 2025 16:59:09 -0500 Subject: [PATCH 3/5] wip --- .../tests/signals-vanilla/network-signals-fetch.test.ts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/packages/signals/signals-integration-tests/src/tests/signals-vanilla/network-signals-fetch.test.ts b/packages/signals/signals-integration-tests/src/tests/signals-vanilla/network-signals-fetch.test.ts index 4f0a5d5bb..20471c440 100644 --- a/packages/signals/signals-integration-tests/src/tests/signals-vanilla/network-signals-fetch.test.ts +++ b/packages/signals/signals-integration-tests/src/tests/signals-vanilla/network-signals-fetch.test.ts @@ -124,7 +124,8 @@ test.describe('network signals - fetch', () => { (el) => el.properties!.data.action === 'request' ) expect(requests).toHaveLength(1) - expect(requests[0].properties!.data).toMatchObject({ + const requestData = requests[0].properties!.data + expect(requestData).toMatchObject({ action: 'request', contentType: 'application/json', url: 'http://localhost/test', @@ -133,12 +134,14 @@ test.describe('network signals - fetch', () => { requestId: NON_EMPTY_STRING, ...commonSignalData, }) + const requestId = requestData.requestId const responses = networkEvents.filter( (el) => el.properties!.data.action === 'response' ) expect(responses).toHaveLength(1) - expect(responses[0].properties!.data).toMatchObject({ + const responseData = responses[0].properties!.data + expect(responseData).toMatchObject({ action: 'response', contentType: 'application/json', url: 'http://localhost/test', @@ -148,6 +151,7 @@ test.describe('network signals - fetch', () => { requestId: NON_EMPTY_STRING, ...commonSignalData, }) + expect(responseData.requestId).toEqual(requestId) }) test('can handle relative url paths', async () => { From 4991bc92884bf85ad2dd2badcc4fbe6a70f80c9c Mon Sep 17 00:00:00 2001 From: Seth Silesky <5115498+silesky@users.noreply.github.com> Date: Wed, 9 Jul 2025 17:03:01 -0500 Subject: [PATCH 4/5] add network generator test --- .../__tests__/network-generator.test.ts | 22 +++++++++++++------ 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/packages/signals/signals/src/core/signal-generators/network-gen/__tests__/network-generator.test.ts b/packages/signals/signals/src/core/signal-generators/network-gen/__tests__/network-generator.test.ts index ee3a27bef..abb5f06e1 100644 --- a/packages/signals/signals/src/core/signal-generators/network-gen/__tests__/network-generator.test.ts +++ b/packages/signals/signals/src/core/signal-generators/network-gen/__tests__/network-generator.test.ts @@ -77,7 +77,9 @@ describe(NetworkGenerator, () => { unregister() }) - + const networkSignalMatcher = { + data: { requestId: expect.stringMatching(/.+/) }, + } it('should register and emit signals on fetch requests and responses if on same domain', async () => { const mockEmitter = { emit: jest.fn() } const networkGenerator = new TestNetworkGenerator() @@ -95,7 +97,9 @@ describe(NetworkGenerator, () => { expect(mockEmitter.emit.mock.calls.length).toBe(2) const [first, second] = mockEmitter.emit.mock.calls - expect(first[0]).toMatchInlineSnapshot(` + expect(first[0]).toMatchInlineSnapshot( + networkSignalMatcher, + ` { "anonymousId": "", "context": { @@ -121,16 +125,19 @@ describe(NetworkGenerator, () => { "title": "", "url": "http://localhost/", }, - "requestId": "cetsvycymt", + "requestId": StringMatching /\\.\\+/, "url": "http://localhost/test", }, "index": undefined, "timestamp": , "type": "network", } - `) + ` + ) - expect(second[0]).toMatchInlineSnapshot(` + expect(second[0]).toMatchInlineSnapshot( + networkSignalMatcher, + ` { "anonymousId": "", "context": { @@ -156,7 +163,7 @@ describe(NetworkGenerator, () => { "title": "", "url": "http://localhost/", }, - "requestId": "cetsvycymt", + "requestId": StringMatching /\\.\\+/, "status": 200, "url": "http://localhost/test", }, @@ -164,7 +171,8 @@ describe(NetworkGenerator, () => { "timestamp": , "type": "network", } - `) + ` + ) unregister() }) From 1a412b926a74cd8069bc9f7dde7a62cbe1e067c6 Mon Sep 17 00:00:00 2001 From: Seth Silesky <5115498+silesky@users.noreply.github.com> Date: Wed, 9 Jul 2025 17:16:10 -0500 Subject: [PATCH 5/5] fix CI --- meta-tests/check-dts.ts | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/meta-tests/check-dts.ts b/meta-tests/check-dts.ts index 90adac3ac..cdb262cee 100644 --- a/meta-tests/check-dts.ts +++ b/meta-tests/check-dts.ts @@ -2,6 +2,7 @@ import { exec } from 'child_process' import { promisify } from 'util' import path from 'path' import fs from 'fs' +import getPackages from 'get-monorepo-packages' /** * This script is for extra typechecking of the built .d.ts files in {package_name}/dist/types/*. @@ -11,13 +12,19 @@ import fs from 'fs' */ const execa = promisify(exec) -const allPublicPackageDirNames = [ - 'browser', - 'core', - 'node', - 'signals/signals', - 'signals/signals-runtime', -] as const +// Get public packages programmatically +const packages = getPackages(path.join(__dirname, '..')) +const publicPackageNames = [ + '@segment/analytics-next', + '@segment/analytics-core', + '@segment/analytics-node', + '@segment/analytics-signals', +] + +const allPublicPackageDirNames = packages + .filter((pkg) => publicPackageNames.includes(pkg.package.name)) + .map((pkg) => path.relative('packages', pkg.location)) + .sort() as readonly string[] type PackageDirName = typeof allPublicPackageDirNames[number]