Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Changelog

All notable changes to this project will be documented in this file.

## [1.2.0] - 2026-04-10

### Added
- Added a persistent `deviceId` field to all SDK-generated events and to `analytics.user()`.
- Added `deviceIdKey` to `AnalyticsConfig` for customizing persisted storage keys.
- Added React Native guidance for `react-native-get-random-values` when `crypto.getRandomValues()` is unavailable.

### Changed
- Switched SDK-generated IDs from UUIDv4 to UUIDv7 via the public `uuid()` helper.
- Updated runtime library context version to `1.2.0`.
- Updated README, quick start, React Native setup, deployment, examples, and publishing docs for `deviceId`, UUIDv7, and the `1.2.0` release.

### Notes
- `analytics.reset()` still clears `userId` and traits, but now preserves the persisted `deviceId`.
- `anonymousId` remains overrideable per event; `deviceId` does not.
10 changes: 5 additions & 5 deletions DEPLOYMENT_GUIDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ npm publish --access public
# Initialize git
git init
git add .
git commit -m "Initial release v1.0.0"
git commit -m "Release v1.2.0"

# Create repo on GitHub: https://github.com/new
# Repository name: analytics
Expand All @@ -40,7 +40,7 @@ git branch -M main
git push -u origin main

# Create release
git tag v1.0.0
git tag v1.2.0
git push --tags
```

Expand All @@ -62,14 +62,14 @@ npm install @stickyqr/analytics

```html
<!-- Or via CDN -->
<script src="https://unpkg.com/@stickyqr/analytics@1.0.0/dist/index.umd.js"></script>
<script src="https://unpkg.com/@stickyqr/analytics@1.2.0/dist/index.umd.js"></script>
```

### React Native / Expo

```bash
npx expo install @stickyqr/analytics
npx expo install @react-native-async-storage/async-storage expo-constants expo-device
npx expo install @react-native-async-storage/async-storage expo-constants expo-device react-native-get-random-values
```

### Node.js
Expand Down Expand Up @@ -192,7 +192,7 @@ const userId = analytics.storage.getSync('userId');

- **Bundle Size**: 17KB (minified)
- **TypeScript**: Full type support
- **Dependencies**: Zero runtime dependencies
- **Dependencies**: 1 runtime dependency (`uuid`)
- **Peer Dependencies**: Optional (React Native only)

---
Expand Down
53 changes: 33 additions & 20 deletions PUBLISHING.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,14 +44,15 @@ git push -u origin main

Before publishing, ensure:

- [ ] All tests pass: `npm test`
- [ ] All tests pass: `npm test -- --watchman=false`
- [ ] Linter passes: `npm run lint`
- [ ] Build succeeds: `npm run build`
- [ ] Version updated in `package.json`
- [ ] CHANGELOG.md updated
- [ ] README.md is accurate
- [ ] All examples work
- [ ] Documentation is complete
- [ ] Runtime dependency list is correct (`uuid` is the only runtime dependency in 1.2.0)

## Publishing to NPM

Expand All @@ -60,7 +61,7 @@ Before publishing, ensure:
```bash
# 1. Ensure package.json is correct
# - name: "@stickyqr/analytics"
# - version: "1.0.0"
# - version: "1.2.0"
# - main, module, types fields set
# - files array includes "dist"

Expand Down Expand Up @@ -133,7 +134,7 @@ npm version major

```bash
# Create release branch
git checkout -b release/1.1.0
git checkout -b release/1.2.0

# Update version
npm version minor
Expand All @@ -142,10 +143,10 @@ npm version minor
# Add release notes

# Commit changes
git commit -am "chore: prepare release 1.1.0"
git commit -am "chore: prepare release 1.2.0"

# Push for review
git push origin release/1.1.0
git push origin release/1.2.0
```

### 2. Review & Test
Expand All @@ -160,10 +161,10 @@ git push origin release/1.1.0
```bash
# Merge to main
git checkout main
git merge release/1.1.0
git merge release/1.2.0

# Tag release
git tag v1.1.0
git tag v1.2.0

# Push
git push origin main --tags
Expand All @@ -180,8 +181,8 @@ npm publish

# Create GitHub Release
# Go to: https://github.com/stickyqr/analytics/releases/new
# - Tag: v1.1.0
# - Title: v1.1.0
# - Tag: v1.2.0
# - Title: v1.2.0
# - Description: Copy from CHANGELOG.md
```

Expand Down Expand Up @@ -229,12 +230,12 @@ Fix:

```bash
# 1. Create and push tag
git tag v1.1.0
git push origin v1.1.0
git tag v1.2.0
git push origin v1.2.0

# 2. Create GitHub Release
# Go to: https://github.com/stickyqr/analytics/releases/new
# - Select tag: v1.1.0
# - Select tag: v1.2.0
# - Click "Publish release"

# 3. GitHub Actions will automatically:
Expand Down Expand Up @@ -270,6 +271,17 @@ All notable changes to this project will be documented in this file.
### Security
- Security fixes

## [1.2.0] - 2026-04-10

### Added
- Persistent `deviceId` on SDK-generated events
- `deviceIdKey` config support
- React Native `react-native-get-random-values` setup guidance

### Changed
- SDK-generated IDs now use UUIDv7
- Release metadata and docs updated for 1.2.0

## [1.1.0] - 2024-12-20

### Added
Expand Down Expand Up @@ -312,17 +324,17 @@ npm view @stickyqr/analytics
npm view @stickyqr/analytics versions

# View specific version
npm view @stickyqr/analytics@1.0.0
npm view @stickyqr/analytics@1.2.0
```

### Unpublish (Use Carefully!)

```bash
# Unpublish specific version (only within 72 hours)
npm unpublish @stickyqr/analytics@1.0.0
npm unpublish @stickyqr/analytics@1.2.0

# Deprecate instead (preferred)
npm deprecate @stickyqr/analytics@1.0.0 "This version has a critical bug, please upgrade to 1.0.1"
npm deprecate @stickyqr/analytics@1.2.0 "This version has a critical bug, please upgrade to 1.2.1"
```

### Update Package Info
Expand All @@ -338,7 +350,7 @@ npm publish --readme-only

```bash
# Update version with pre-release tag
npm version 1.1.0-beta.1
npm version 1.2.0-beta.1

# Publish with tag
npm publish --tag beta
Expand All @@ -351,7 +363,7 @@ npm install @stickyqr/analytics@beta

```bash
# Tag as latest
npm dist-tag add @stickyqr/analytics@1.1.0 latest
npm dist-tag add @stickyqr/analytics@1.2.0 latest
```

## Package Access Control
Expand Down Expand Up @@ -442,7 +454,8 @@ npm publish

1. **Always test before publishing**
```bash
npm test && npm run build
pnpm exec jest --config jest.config.cjs --passWithNoTests --runInBand --watchman=false
pnpm run build
```

2. **Use semantic versioning correctly**
Expand All @@ -456,7 +469,7 @@ npm publish

4. **Tag releases in git**
```bash
git tag v1.0.0
git tag v1.2.0
git push --tags
```

Expand All @@ -467,7 +480,7 @@ npm publish

6. **Deprecate, don't unpublish**
```bash
npm deprecate @stickyqr/analytics@1.0.0 "Upgrade to 1.0.1"
npm deprecate @stickyqr/analytics@1.2.0 "Upgrade to 1.2.1"
```

7. **Test in multiple environments**
Expand Down
7 changes: 5 additions & 2 deletions QUICKSTART.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ analytics.identify('user-123', {
### Option 2: CDN (Browser)

```html
<script src="https://cdn.stickyqr.com/analytics/1.0.0/index.umd.js"></script>
<script src="https://cdn.stickyqr.com/analytics/1.2.0/index.umd.js"></script>
<script>
const analytics = new StickyQRAnalytics.Analytics({
writeKey: 'your-write-key'
Expand Down Expand Up @@ -129,6 +129,8 @@ analytics.page('Pricing', 'Marketing', { plan: 'enterprise' });
analytics.reset();
```

`analytics.reset()` rotates `anonymousId` and clears the current user state, but keeps the persisted `deviceId`.

## Backend Setup

Your backend needs to implement one endpoint to receive events:
Expand Down Expand Up @@ -302,6 +304,7 @@ const analytics = new Analytics({

// Storage
anonymousIdKey: 'stickyqr_analytics_anonymous_id',
deviceIdKey: 'stickyqr_analytics_device_id',
userIdKey: 'stickyqr_analytics_user_id',

// Plugins
Expand All @@ -319,7 +322,7 @@ const analytics = new Analytics({
});

// View current user
console.log(analytics.user());
console.log(analytics.user()); // includes userId, anonymousId, deviceId, and traits

// View analytics state
analytics.debug();
Expand Down
19 changes: 16 additions & 3 deletions REACT_NATIVE_SETUP.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ Complete guide for using `@stickyqr/analytics` with React Native and Expo 54.
npx expo install @stickyqr/analytics

# Install required peer dependencies
npx expo install @react-native-async-storage/async-storage expo-constants expo-device
npx expo install @react-native-async-storage/async-storage expo-constants expo-device react-native-get-random-values
```

### For Bare React Native Projects
Expand All @@ -25,6 +25,7 @@ npm install @stickyqr/analytics
# Install peer dependencies
npm install @react-native-async-storage/async-storage
npm install expo-constants expo-device
npm install react-native-get-random-values

# Link native modules (if not using autolinking)
cd ios && pod install && cd ..
Expand All @@ -36,6 +37,7 @@ cd ios && pod install && cd ..

```typescript
// lib/analytics.ts
import 'react-native-get-random-values';
import { Analytics } from '@stickyqr/analytics';

export const analytics = new Analytics({
Expand All @@ -51,6 +53,7 @@ export const analytics = new Analytics({

```typescript
// contexts/AnalyticsContext.tsx
import 'react-native-get-random-values';
import React, { createContext, useContext, useEffect, useState } from 'react';
import { Analytics } from '@stickyqr/analytics';

Expand Down Expand Up @@ -228,7 +231,7 @@ function SettingsScreen() {

const handleLogout = async () => {
analytics.track('User Logged Out');
await analytics.reset(); // Clear user data
await analytics.reset(); // Clear user data, preserve deviceId
};

return <Button title="Logout" onPress={handleLogout} />;
Expand Down Expand Up @@ -313,6 +316,7 @@ The SDK automatically collects app info if `expo-constants` is installed:
### AsyncStorage

User data (user ID, traits, anonymous ID) is automatically persisted using `@react-native-async-storage/async-storage`.
The SDK also persists `deviceId` separately using the same storage layer.

## Configuration

Expand All @@ -335,10 +339,19 @@ const analytics = new Analytics({

// Storage keys
anonymousIdKey: 'stickyqr_analytics_anonymous_id',
deviceIdKey: 'stickyqr_analytics_device_id',
userIdKey: 'stickyqr_analytics_user_id'
});
```

## React Native Randomness

UUIDv7 generation requires `crypto.getRandomValues()`. If your React Native runtime does not expose it yet, install `react-native-get-random-values` and import it before initializing the SDK:

```typescript
import 'react-native-get-random-values';
```

## Troubleshooting

### AsyncStorage not found
Expand Down Expand Up @@ -451,7 +464,7 @@ See complete examples in:

The SDK respects user privacy:
- ✅ Data stored locally (AsyncStorage)
- ✅ User can be reset with `analytics.reset()`
- ✅ User can be reset with `analytics.reset()` without rotating `deviceId`
- ✅ No tracking until initialized
- ✅ Full control over data sent

Expand Down
Loading
Loading