Skip to content
Open
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
45 changes: 45 additions & 0 deletions packages/javascript/example/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,50 @@ <h2>Context Management</h2>
<br /><br />
<button id="btn-set-context">Set Context</button>
</section>
<section>
<h2>Breadcrumbs Management</h2>
<label for="breadcrumbMessage">Breadcrumb Message</label>
<input type="text" id="breadcrumbMessage" placeholder="User performed action" />
<br /><br />
<label for="breadcrumbType">Type</label>
<select id="breadcrumbType">
<option value="default">default</option>
<option value="request">request</option>
<option value="ui">ui</option>
<option value="navigation">navigation</option>
<option value="logic">logic</option>
<option value="error">error</option>
</select>
<br /><br />
<label for="breadcrumbLevel">Level</label>
<select id="breadcrumbLevel">
<option value="info">info</option>
<option value="debug">debug</option>
<option value="warning">warning</option>
<option value="error">error</option>
<option value="fatal">fatal</option>
</select>
<br /><br />
<label for="breadcrumbCategory">Category (optional)</label>
<input type="text" id="breadcrumbCategory" placeholder="ui.click" />
<br /><br />
<button id="btn-add-breadcrumb">Add Breadcrumb</button>
<button id="btn-get-breadcrumbs">Get Breadcrumbs</button>
<button id="btn-clear-breadcrumbs">Clear Breadcrumbs</button>
<div id="breadcrumbs-output" style="margin-top: 15px; margin-bottom: 30px; padding: 10px; background: rgba(36, 39, 50, 0.68); border-radius: 3px; max-height: 200px; overflow-y: auto; white-space: pre-wrap; font-family: monospace; font-size: 12px;"></div>
<h2>Test All Breadcrumb Types <small>Quick examples for each type</small></h2>
<div style="display: grid; grid-template-columns: repeat(2, 1fr); gap: 10px;">
<button id="btn-test-default">Default Event</button>
<button id="btn-test-request">Request (Fetch)</button>
<button id="btn-test-ui">UI Click</button>
<button id="btn-test-navigation">Navigation</button>
<button id="btn-test-logic">Logic Operation</button>
<button id="btn-test-error">Error Event</button>
</div>
<div style="margin-top: 10px; display: flex; gap: 10px;">
<button id="btn-test-all-types" style="flex: 1; background: #2ecc71;">▶Run All Types Sequence</button>
</div>
</section>
<script src="https://unpkg.com/vue@2"></script>
<section>
<h2>Test Vue integration: $root</h2>
Expand Down Expand Up @@ -259,6 +303,7 @@ <h2>Test Vue integration: &lt;test-component&gt;</h2>
context: {
rootContextSample: '12345',
},
// trackClicks: true
});
</script>
</body>
Expand Down
270 changes: 270 additions & 0 deletions packages/javascript/example/sample-errors.js
Original file line number Diff line number Diff line change
Expand Up @@ -123,3 +123,273 @@ buttonSetContext.addEventListener('click', () => {

window.hawk.setContext(context);
});

/**
* Breadcrumbs Management
*/
const buttonAddBreadcrumb = document.getElementById('btn-add-breadcrumb');
const buttonGetBreadcrumbs = document.getElementById('btn-get-breadcrumbs');
const buttonClearBreadcrumbs = document.getElementById('btn-clear-breadcrumbs');
const breadcrumbsOutput = document.getElementById('breadcrumbs-output');

buttonAddBreadcrumb.addEventListener('click', () => {
const message = document.getElementById('breadcrumbMessage').value;
const type = document.getElementById('breadcrumbType').value;
const level = document.getElementById('breadcrumbLevel').value;
const category = document.getElementById('breadcrumbCategory').value;

if (!message.trim()) {
alert('Breadcrumb message is required');
return;
}

window.hawk.addBreadcrumb({
message,
type,
level,
...(category.trim() && { category }),
data: {
timestamp: new Date().toISOString(),
custom: 'manual breadcrumb',
},
});

breadcrumbsOutput.textContent = `✓ Breadcrumb added: ${message}`;
});

buttonGetBreadcrumbs.addEventListener('click', () => {
const breadcrumbs = window.hawk.getBreadcrumbs();

if (breadcrumbs.length === 0) {
breadcrumbsOutput.textContent = 'No breadcrumbs yet';
return;
}

breadcrumbsOutput.textContent = JSON.stringify(breadcrumbs, null, 2);
});

buttonClearBreadcrumbs.addEventListener('click', () => {
window.hawk.clearBreadcrumbs();
breadcrumbsOutput.textContent = '✓ Breadcrumbs cleared';
});

/**
* Test All Breadcrumb Types
*/
const buttonTestDefault = document.getElementById('btn-test-default');
const buttonTestRequest = document.getElementById('btn-test-request');
const buttonTestUI = document.getElementById('btn-test-ui');
const buttonTestNavigation = document.getElementById('btn-test-navigation');
const buttonTestLogic = document.getElementById('btn-test-logic');
const buttonTestError = document.getElementById('btn-test-error');
const buttonTestAllTypes = document.getElementById('btn-test-all-types');

// Test Default breadcrumb
buttonTestDefault.addEventListener('click', () => {
window.hawk.addBreadcrumb({
type: 'default',
level: 'info',
category: 'user.action',
message: 'User clicked on default event button',
data: {
action: 'button_click',
context: 'breadcrumb_testing',
},
});
breadcrumbsOutput.textContent = '✓ Default breadcrumb added';
});

// Test Request breadcrumb (automatic via fetch)
buttonTestRequest.addEventListener('click', async () => {
breadcrumbsOutput.textContent = 'Testing request breadcrumb...';

try {
const response = await fetch('https://api.github.com/zen');
const text = await response.text();
breadcrumbsOutput.textContent = `✓ Request breadcrumb added (${response.status}): "${text}"`;
} catch (error) {
breadcrumbsOutput.textContent = `✗ Request failed: ${error.message}`;
}
});

// Test UI breadcrumb
buttonTestUI.addEventListener('click', () => {
window.hawk.addBreadcrumb({
type: 'ui',
level: 'info',
category: 'ui.click',
message: 'Click on test button#btn-test-ui',
data: {
selector: 'button#btn-test-ui',
text: '👆 UI Click',
tagName: 'BUTTON',
coordinates: {
x: 100,
y: 200,
},
},
});
breadcrumbsOutput.textContent = '✓ UI Click breadcrumb added';
});

// Test Navigation breadcrumb
buttonTestNavigation.addEventListener('click', () => {
const currentUrl = window.location.href;
const testUrl = currentUrl.split('#')[0] + '#breadcrumb-test-' + Date.now();

window.hawk.addBreadcrumb({
type: 'navigation',
level: 'info',
category: 'navigation',
message: `Navigated to ${testUrl}`,
data: {
from: currentUrl,
to: testUrl,
method: 'hash_change',
},
});

// Actually change the hash to trigger real navigation breadcrumb too
window.location.hash = 'breadcrumb-test-' + Date.now();

breadcrumbsOutput.textContent = '✓ Navigation breadcrumb added';
});

// Test Logic breadcrumb
buttonTestLogic.addEventListener('click', () => {
// Simulate some logic operations
const startTime = performance.now();

/**
* Complex calculation for testing
*
* @param {number} n - Number of iterations
* @returns {number} Calculation result
*/
function complexCalculation(n) {
let result = 0;

for (let i = 0; i < n; i++) {
result += Math.sqrt(i);
}

return result;
}

const result = complexCalculation(10000);
const duration = performance.now() - startTime;

window.hawk.addBreadcrumb({
type: 'logic',
level: 'debug',
category: 'calculation.complex',
message: 'Performed complex calculation',
data: {
operation: 'complexCalculation',
iterations: 10000,
result: result,
durationMs: duration.toFixed(2),
},
});

breadcrumbsOutput.textContent = `✓ Logic breadcrumb added (${duration.toFixed(2)}ms)`;
});

// Test Error breadcrumb
buttonTestError.addEventListener('click', () => {
try {
// Intentionally cause an error but catch it
JSON.parse('invalid json {{{');
} catch (error) {
window.hawk.addBreadcrumb({
type: 'error',
level: 'error',
category: 'json.parse',
message: `JSON parse error: ${error.message}`,
data: {
error: error.name,
message: error.message,
input: 'invalid json {{{',
},
});

breadcrumbsOutput.textContent = `✓ Error breadcrumb added: ${error.message}`;
}
});

// Test All Types in sequence
buttonTestAllTypes.addEventListener('click', async () => {
breadcrumbsOutput.textContent = 'Running all breadcrumb types...';

// 1. Default
window.hawk.addBreadcrumb({
type: 'default',
level: 'info',
message: 'Sequence started',
});

await new Promise(resolve => setTimeout(resolve, 200));

// 2. Logic
window.hawk.addBreadcrumb({
type: 'logic',
level: 'debug',
category: 'sequence.step',
message: 'Processing step 1',
data: {
step: 1,
},
});

await new Promise(resolve => setTimeout(resolve, 200));

// 3. UI
window.hawk.addBreadcrumb({
type: 'ui',
level: 'info',
category: 'ui.interaction',
message: 'User initiated sequence',
data: {
action: 'sequence_test',
},
});

await new Promise(resolve => setTimeout(resolve, 200));

// 4. Request
try {
await fetch('https://api.github.com/zen');
} catch (error) {
// Fetch will be captured automatically
}

await new Promise(resolve => setTimeout(resolve, 200));

// 5. Navigation
window.hawk.addBreadcrumb({
type: 'navigation',
level: 'info',
message: 'Internal route change',
data: {
route: '/test',
},
});

await new Promise(resolve => setTimeout(resolve, 200));

// 6. Error
try {
throw new Error('Test error in sequence');
} catch (error) {
window.hawk.addBreadcrumb({
type: 'error',
level: 'warning',
message: `Caught error: ${error.message}`,
data: {
error: error.name,
},
});
}

breadcrumbsOutput.textContent = '✓ All breadcrumb types added! Check "Get Breadcrumbs"';
});
5 changes: 3 additions & 2 deletions packages/javascript/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@
"scripts": {
"dev": "vite",
"build": "vite build",
"stats": "size-limit > stats.txt"
"stats": "size-limit > stats.txt",
"lint": "eslint --fix \"src/**/*.{js,ts}\""
},
"repository": {
"type": "git",
Expand All @@ -35,7 +36,7 @@
},
"homepage": "https://github.com/codex-team/hawk.javascript#readme",
"dependencies": {
"@hawk.so/types": "^0.1.36",
"@hawk.so/types": "^0.1.38",
"error-stack-parser": "^2.1.4"
},
"devDependencies": {
Expand Down
Loading
Loading