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
186 changes: 65 additions & 121 deletions samples/language-service-sample/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,137 +43,72 @@ window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', (e)

initTheme();

// Examples data
const exampleCases = [
{
id: 'math',
title: 'Mathematical Expression',
description: 'Basic math operations with variables',
expression: '(x + y) * multiplier + sqrt(16)',
context: {
x: 10,
y: 5,
multiplier: 3
}
},
{
id: 'arrays',
title: 'Working with Arrays',
description: 'Array functions like sum, min, max',
expression: 'sum(numbers) + max(numbers) - min(numbers)',
context: {
numbers: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
values: [15, 25, 35]
}
},
{
id: 'objects',
title: 'Object Manipulation',
description: 'Access nested object properties',
expression: 'user.profile.score * level.multiplier + bonus.points',
context: {
user: {
name: "Alice",
profile: {
score: 85,
rank: "Gold"
}
},
level: {
current: 5,
multiplier: 1.5
},
bonus: {
points: 100,
active: true
}
}
},
{
id: 'map-filter',
title: 'Map and Filter Functions',
description: 'Transform and filter data with callbacks',
expression: 'sum(map(filter(items, item => item > 3), x => x * 2))',
context: {
items: [1, 2, 3, 4, 5, 6, 7, 8],
threshold: 3
}
},
{
id: 'complex',
title: 'Complex Objects',
description: 'Work with deeply nested data structures',
expression: 'company.departments[0].employees.length * company.settings.bonusRate + sum(map(company.departments, d => d.budget))',
context: {
company: {
name: "TechCorp",
departments: [
{
name: "Engineering",
budget: 500000,
employees: ["John", "Jane", "Bob"]
},
{
name: "Marketing",
budget: 200000,
employees: ["Alice", "Carol"]
}
],
settings: {
bonusRate: 0.15,
fiscalYear: 2024
}
}
}
},
{
id: 'data-transform',
title: 'Data Transformation',
description: 'Flatten nested objects and transform rows',
expression: "map(f(row) = {_id: row.rowId} + flatten(row.data, ''), $event)",
context: {
"$event": [
{"rowId": 1, "state": "saved", "data": { "InventoryId": 1256, "Description": "Bal", "Weight": { "Unit": "g", "Amount": 120 } }},
{"rowId": 2, "state": "new", "data": { "InventoryId": 2344, "Description": "Basket", "Weight": { "Unit": "g", "Amount": 300 } }},
{"rowId": 3, "state": "unchanged", "data": { "InventoryId": 9362, "Description": "Wood", "Weight": { "Unit": "kg", "Amount": 18 } }}
]
}
}
];
// Copy example link to clipboard
function copyExampleLink(exampleId, button) {
const url = new URL(window.location.href);
url.search = '';
url.searchParams.set('example', exampleId);
navigator.clipboard.writeText(url.toString()).then(() => {
// Show checkmark briefly
const icon = button.querySelector('svg');
const originalPath = icon.innerHTML;
icon.innerHTML = '<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7" />';
button.classList.add('text-green-500', 'dark:text-green-400');
setTimeout(() => {
icon.innerHTML = originalPath;
button.classList.remove('text-green-500', 'dark:text-green-400');
}, 1500);
});
}

// Render examples sidebar
function renderExamplesSidebar() {
const examplesList = document.getElementById('examplesList');
if (!examplesList) return;

examplesList.innerHTML = exampleCases.map(example => `

Copilot AI Jan 23, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

exampleCases is referenced here but no longer defined in this file and there is no other definition in the repo, so this will throw a ReferenceError at runtime unless a global exampleCases is provided (e.g., by the new examples.js). Either reintroduce the data here or ensure examples.js exists, defines exampleCases on the global scope, and is loaded before this script.

Suggested change
examplesList.innerHTML = exampleCases.map(example => `
const examples = (window.exampleCases || []);
examplesList.innerHTML = examples.map(example => `

Copilot uses AI. Check for mistakes.
<button
class="example-item w-full text-left p-3 rounded-lg transition-all duration-200
hover:bg-white dark:hover:bg-[#2d2d2d]
hover:shadow-sm hover:border-indigo-200 dark:hover:border-[#3c3c3c]
border border-transparent
group"
data-example-id="${example.id}"
>
<div class="flex items-start gap-2">
<div class="flex-shrink-0 w-6 h-6 rounded bg-indigo-100 dark:bg-[#3c3c3c] flex items-center justify-center mt-0.5">
<svg class="w-3.5 h-3.5 text-indigo-600 dark:text-[#569cd6]" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 10V3L4 14h7v7l9-11h-7z" />
</svg>
<div class="example-container relative group/container">
<button
class="example-item w-full text-left p-3 rounded-lg transition-all duration-200
hover:bg-white dark:hover:bg-[#2d2d2d]
hover:shadow-sm hover:border-indigo-200 dark:hover:border-[#3c3c3c]
border border-transparent
group"
data-example-id="${example.id}"
>
<div class="flex items-start gap-2">
<div class="flex-shrink-0 w-6 h-6 rounded bg-indigo-100 dark:bg-[#3c3c3c] flex items-center justify-center mt-0.5">
<svg class="w-3.5 h-3.5 text-indigo-600 dark:text-[#569cd6]" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 10V3L4 14h7v7l9-11h-7z" />
</svg>
</div>
<div class="flex-1 min-w-0">
<p class="text-sm font-medium text-gray-800 dark:text-[#cccccc] truncate group-hover:text-indigo-600 dark:group-hover:text-[#569cd6]">
${example.title}
</p>
<p class="text-xs text-gray-500 dark:text-[#808080] mt-0.5 line-clamp-2">
${example.description}
</p>
</div>
</div>
<div class="flex-1 min-w-0">
<p class="text-sm font-medium text-gray-800 dark:text-[#cccccc] truncate group-hover:text-indigo-600 dark:group-hover:text-[#569cd6]">
${example.title}
</p>
<p class="text-xs text-gray-500 dark:text-[#808080] mt-0.5 line-clamp-2">
${example.description}
</p>
</div>
</div>
</button>
</button>
<button
class="copy-link-btn absolute top-2 right-2 p-1.5 rounded-md
opacity-0 group-hover/container:opacity-100
bg-gray-100 dark:bg-[#3c3c3c] hover:bg-gray-200 dark:hover:bg-[#4c4c4c]
text-gray-500 dark:text-[#808080] hover:text-indigo-600 dark:hover:text-[#569cd6]
transition-all duration-200"
data-example-id="${example.id}"
title="Copy link to example"
>
<svg class="w-3.5 h-3.5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
</svg>
</button>
</div>
`).join('');

// Add click handlers
// Add click handlers for loading examples
examplesList.querySelectorAll('.example-item').forEach(button => {
button.addEventListener('click', () => {
const exampleId = button.dataset.exampleId;
Expand All @@ -183,6 +118,15 @@ function renderExamplesSidebar() {
}
});
});

// Add click handlers for copy link buttons
examplesList.querySelectorAll('.copy-link-btn').forEach(button => {
button.addEventListener('click', (e) => {
e.stopPropagation();
const exampleId = button.dataset.exampleId;
copyExampleLink(exampleId, button);
});
});
}

// Load example into editors
Expand Down
97 changes: 97 additions & 0 deletions samples/language-service-sample/examples.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
// Example cases for the language service sample
const exampleCases = [
{
id: 'math',
title: 'Mathematical Expression',
description: 'Basic math operations with variables',
expression: '(x + y) * multiplier + sqrt(16)',
context: {
x: 10,
y: 5,
multiplier: 3
}
},
{
id: 'arrays',
title: 'Working with Arrays',
description: 'Array functions like sum, min, max',
expression: 'sum(numbers) + max(numbers) - min(numbers)',
context: {
numbers: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
values: [15, 25, 35]
}
},
{
id: 'objects',
title: 'Object Manipulation',
description: 'Access nested object properties',
expression: 'user.profile.score * level.multiplier + bonus.points',
context: {
user: {
name: "Alice",
profile: {
score: 85,
rank: "Gold"
}
},
level: {
current: 5,
multiplier: 1.5
},
bonus: {
points: 100,
active: true
}
}
},
{
id: 'map-filter',
title: 'Map and Filter Functions',
description: 'Transform and filter data with callbacks',
expression: 'sum(\n map(\n f(x) = x * 2, \n filter(\n f(i) = i > threshold, \n items\n )\n )\n) / length(items)',
context: {
items: [1, 2, 3, 4, 5, 6, 7, 8],
threshold: 3
}
},
{
id: 'complex',
title: 'Complex Objects',
description: 'Work with deeply nested data structures',
expression: 'length(company.departments[0].employees) * company.settings.bonusRate + sum(map(f(d) = d.budget, company.departments))',
context: {
company: {
name: "TechCorp",
departments: [
{
name: "Engineering",
budget: 500000,
employees: ["John", "Jane", "Bob"]
},
{
name: "Marketing",
budget: 200000,
employees: ["Alice", "Carol"]
}
],
settings: {
bonusRate: 0.15,
fiscalYear: 2024
}
}
}
},
{
id: 'data-transform',
title: 'Data Transformation',
description: 'Flatten nested objects and transform rows',
expression: "map(f(row) = {_id: row.rowId} + flatten(row.data, ''), $event)",
context: {
"$event": [
{"rowId": 1, "state": "saved", "data": { "InventoryId": 1256, "Description": "Bal", "Weight": { "Unit": "g", "Amount": 120 } }},
{"rowId": 2, "state": "new", "data": { "InventoryId": 2344, "Description": "Basket", "Weight": { "Unit": "g", "Amount": 300 } }},
{"rowId": 3, "state": "unchanged", "data": { "InventoryId": 9362, "Description": "Wood", "Weight": { "Unit": "kg", "Amount": 18 } }}
]
}
}
];
1 change: 1 addition & 0 deletions samples/language-service-sample/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,7 @@ <h1 class="text-xl font-bold bg-gradient-to-r from-indigo-600 to-purple-600 dark
<span>Saved to localStorage</span>
</div>

<script src="examples.js"></script>

Copilot AI Jan 23, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This script tag loads examples.js, but there is no corresponding samples/language-service-sample/examples.js file in the repository, so the browser will 404 this request and any globals (like exampleCases) it is supposed to define will be missing. Please add the file to the sample folder or remove this tag and keep the examples inline.

Suggested change
<script src="examples.js"></script>

Copilot uses AI. Check for mistakes.
<script src="app.js"></script>
</body>
</html>
2 changes: 1 addition & 1 deletion samples/language-service-sample/serve-sample.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ const server = http.createServer((req, res) => {

if (urlPath === '/' || urlPath === '/index.html') {
urlPath = 'samples/language-service-sample/index.html';
} else if (urlPath === '/styles.css' || urlPath === '/app.js') {
} else if (urlPath === '/styles.css' || urlPath === '/app.js' || urlPath === '/examples.js') {

Copilot AI Jan 23, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The server is configured to serve /examples.js from samples/language-service-sample/examples.js, but that file does not exist, so requests to this path will always return 404. Once examples.js is added (or if you decide to inline examples instead), this route should be updated accordingly.

Suggested change
} else if (urlPath === '/styles.css' || urlPath === '/app.js' || urlPath === '/examples.js') {
} else if (urlPath === '/styles.css' || urlPath === '/app.js') {

Copilot uses AI. Check for mistakes.
// Serve sample-specific files from the sample folder
urlPath = 'samples/language-service-sample' + urlPath;
}
Expand Down