From 1f7bdb11907b45229b83a3df6724edbb23d1638c Mon Sep 17 00:00:00 2001 From: sardhak addepalli <42747069+bazingga08@users.noreply.github.com> Date: Thu, 5 Nov 2026 16:37:00 +0530 Subject: [PATCH 1/2] events add --platform web: print @straitlink/web trackEvent instead of a raw POST /v1/event The web SDK now has trackEvent (strait-sdk-web#15, ADR 0002), so the web snippet uses the same call as every other platform; the SDK keeps the tap id itself (no localStorage code in the snippet). Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01JfkGWSV4ar1AEGgGnCbGzd --- CHANGELOG.md | 1 + README.md | 2 +- src/events.mjs | 24 +++++++----------------- test/events.test.mjs | 9 +++++++-- 4 files changed, 16 insertions(+), 20 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 86d6f51..bfd6952 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ - `strait test`: one pass/fail list that says you're set up right: the engine answers, the secret key is valid (which workspace, test or live), and the workspace's link domain serves apple-app-site-association and assetlinks.json. Exit 1 on any failure, `--json` for CI. - `strait events add `: prints ready-to-paste event tracking code for React Native, Flutter, iOS, Android or the web (detected from the project files, or `--platform`), using each SDK's real `trackEvent` call. +- `strait events add --platform web` prints `@straitlink/web`'s new `trackEvent` instead of a hand-written `POST /v1/event` (needs the web SDK release that adds it). ## 0.2.2 (4 Nov 2026) diff --git a/README.md b/README.md index 181040e..9d0d18a 100644 --- a/README.md +++ b/README.md @@ -128,7 +128,7 @@ npx @straitlink/cli events add sign_up --platform ios # react-native | flutter npx @straitlink/cli events add purchase ./mobile # [dir]: the app folder, default the current one ``` -Prints ready-to-paste code with each SDK's own call: `trackEvent` in React Native (and Expo), Flutter, iOS and Android, using the client `strait init` wrote; on the web, `reportWebOpen` plus the `POST /v1/event` the app SDKs send (`@straitlink/web` has no event helper yet). The platform is detected from `package.json`, `pubspec.yaml`, Gradle files, an `.xcodeproj` or `Package.swift`. Nothing is written. Event names are 1-64 letters, numbers, spaces and `_ . : -`. +Prints ready-to-paste code with each SDK's own call: `trackEvent` in React Native (and Expo), Flutter, iOS and Android, using the client `strait init` wrote; on the web, `reportWebOpen` on page load plus `trackEvent` from `@straitlink/web`. The platform is detected from `package.json`, `pubspec.yaml`, Gradle files, an `.xcodeproj` or `Package.swift`. Nothing is written. Event names are 1-64 letters, numbers, spaces and `_ . : -`. ## Install lines: one constant diff --git a/src/events.mjs b/src/events.mjs index 44b7655..e39ce58 100644 --- a/src/events.mjs +++ b/src/events.mjs @@ -4,7 +4,7 @@ // Flutter 0.9 links.trackEvent(name, value:, currency:, linkId:, clickId:) lib/src/client.dart (no eventId) // iOS 0.10 strait.trackEvent(_:value:currency:linkId:clickId:eventId:completion:) StraitLinks.swift // Android 0.8 client.trackEvent(name, value, currency, linkId, clickId, eventId) StraitClient.kt (blocks) -// Web 0.7 no event helper: the same POST /v1/event as sdk-web/examples/web/src/main.ts +// Web (Unreleased) trackEvent(config, name, { value, currency, eventId }) src/index.ts (sdk-web ADR 0002) // `links` / `StraitLinks.client` are the names `strait init` writes (templates.mjs). import { existsSync, readdirSync } from 'node:fs'; import { join } from 'node:path'; @@ -86,25 +86,15 @@ strait.trackEvent("${n}") { ok in // For revenue add value = 49.99, currency = "USD", eventId = order.id (a retry is counted once). val ok = StraitLinks.client.trackEvent("${n}") `, - web: (n, { key, host }) => `import { reportWebOpen } from '@straitlink/web'; + web: (n, { key, host }) => `import { reportWebOpen, trackEvent } from '@straitlink/web'; const strait = { publishableKey: '${key}', endpoint: 'https://${host}' }; -// On page load: remember the tap this visit came from. -const open = await reportWebOpen(strait); -if (open.clickId) localStorage.setItem('strait_click', open.clickId); +// On page load: counts the open and remembers the tap this visit came from. +await reportWebOpen(strait); -// Where "${n}" happens. @straitlink/web has no event helper yet, so this is the same -// POST /v1/event the app SDKs send. For revenue add value: 49.99, currency: 'USD', eventId: order.id -await fetch(\`\${strait.endpoint}/v1/event\`, { - method: 'POST', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({ - publishableKey: strait.publishableKey, - event: '${n}', - platform: 'web', - clickId: localStorage.getItem('strait_click') ?? undefined, - }), -}); +// Where "${n}" happens. Resolves true when Strait took it; never throws. For revenue add +// { value: 49.99, currency: 'USD', eventId: order.id } (eventId: a repeat is counted once). +await trackEvent(strait, '${n}'); `, }; diff --git a/test/events.test.mjs b/test/events.test.mjs index 551eeae..a375c9a 100644 --- a/test/events.test.mjs +++ b/test/events.test.mjs @@ -28,7 +28,7 @@ test('each platform prints its SDK\'s real event call with the name', async () = flutter: [/import 'links\.dart';/, /await links\.trackEvent\('purchase'\);/, /value: 49\.99, currency: 'USD'/], ios: [/strait\.trackEvent\("purchase"\) \{ ok in/, /eventId: order\.id/], android: [/StraitLinks\.client\.trackEvent\("purchase"\)/, /off the main thread/], - web: [/import \{ reportWebOpen \} from '@straitlink\/web'/, /\/v1\/event/, /event: 'purchase'/, /platform: 'web'/, /clickId/], + web: [/import \{ reportWebOpen, trackEvent \} from '@straitlink\/web'/, /await reportWebOpen\(strait\);/, /await trackEvent\(strait, 'purchase'\);/, /value: 49\.99, currency: 'USD', eventId: order\.id/], }; for (const [platform, patterns] of Object.entries(want)) { const r = await run(['add', 'purchase', '--platform', platform, FIXTURES]); @@ -59,7 +59,12 @@ test('detects the platform from the project files', async () => { const spm = await run(['add', 'signup', dirWith({ 'Package.swift': '// swift-tools-version:5.9' })]); assert.match(spm.out, /strait\.trackEvent\("signup"\)/); const web = await run(['add', 'signup', dirWith({ 'package.json': JSON.stringify({ dependencies: { vite: '5' } }) })]); - assert.match(web.out, /reportWebOpen/); + assert.match(web.out, /trackEvent\(strait, 'signup'\)/); +}); + +test('web uses the SDK call, not a hand-written request', async () => { + const r = await run(['add', 'purchase', '--platform', 'web']); + assert.doesNotMatch(r.out, /fetch\(|\/v1\/event|localStorage/); }); test('web fills in the publishable key and link host from the environment when set', async () => { From 6f5fef038b7392356d77b5dbbe8238b081dc15d8 Mon Sep 17 00:00:00 2001 From: sardhak addepalli <42747069+bazingga08@users.noreply.github.com> Date: Thu, 5 Nov 2026 16:37:13 +0530 Subject: [PATCH 2/2] ADR 0001: note that the web snippet now uses trackEvent Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01JfkGWSV4ar1AEGgGnCbGzd --- docs/adr/0001-strait-test-and-events-add.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/adr/0001-strait-test-and-events-add.md b/docs/adr/0001-strait-test-and-events-add.md index c1f7434..39871fb 100644 --- a/docs/adr/0001-strait-test-and-events-add.md +++ b/docs/adr/0001-strait-test-and-events-add.md @@ -15,6 +15,7 @@ A developer with a secret key and an app, in a terminal or a CI job. the existing `runDoctor` on the workspace's link domain. `strait events add` prints the one call each SDK already has (`trackEvent` in React Native, Flutter, iOS, Android; the web SDK has no event helper, so it prints the same `POST /v1/event` its own example uses). No engine, SDK or database change. + *Update 5 Nov 2026:* the web SDK gained `trackEvent` (strait-sdk-web ADR 0002); the web snippet now prints it. - **New engine endpoint for a combined check.** Rejected: everything needed is already served. - **Write the event code into the user's files.** Rejected: we can't know where their purchase happens; printing is safe and reviewable.