Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
126 commits
Select commit Hold shift + click to select a range
52869bf
Add api-graph
compulim Oct 24, 2025
131dd7c
Add JSON-LD schemas
compulim Oct 25, 2025
c9c81b0
Add flattenedNodeObject
compulim Oct 27, 2025
09f0bfd
Fail when flattening array
compulim Oct 27, 2025
f00bda8
Add more tests for flattening
compulim Oct 27, 2025
80638e4
Expect no warn/error
compulim Oct 27, 2025
a4fb13e
Add doc
compulim Oct 27, 2025
937118a
Add expandArray
compulim Oct 27, 2025
f82e8ac
Add doc
compulim Oct 27, 2025
7b39c48
Add test
compulim Oct 27, 2025
0f2fa87
Add isOfType
compulim Oct 28, 2025
fab9225
Rename to FlatNodeObject
compulim Oct 28, 2025
f24dd7b
Comment
compulim Oct 28, 2025
14b0e34
Use flatNodeObject
compulim Oct 28, 2025
66e7cb0
Add GraphProvider.mergeNode
compulim Oct 28, 2025
7857c1c
Add graph
compulim Oct 29, 2025
7331b96
Add isPartOf auto-linking
compulim Oct 29, 2025
858ecd7
More opinions
compulim Oct 29, 2025
3b2229f
Update comments
compulim Oct 29, 2025
3a4b2a6
Clean up
compulim Oct 29, 2025
f69b9b0
Add test
compulim Oct 29, 2025
bbd7e0c
Remove edge if needed
compulim Oct 29, 2025
66bc3aa
Add specific test case for coloring
compulim Oct 29, 2025
2a6e3d2
Clean up
compulim Oct 29, 2025
66cb6f4
Better test result
compulim Oct 29, 2025
84906e4
Add slantNodeWithFix schema
compulim Oct 29, 2025
7b8d2db
Simplify
compulim Oct 29, 2025
c6b4647
Clean up
compulim Oct 29, 2025
0297d58
Clean up comment
compulim Oct 29, 2025
0cde4b2
Reorder
compulim Oct 29, 2025
f2c41c0
Clean up
compulim Oct 29, 2025
fdffab2
Fix comment
compulim Oct 29, 2025
05a8102
Fix comment
compulim Oct 29, 2025
f9e5691
Fix comment
compulim Oct 29, 2025
4b17bab
First working graph
compulim Nov 4, 2025
93814ea
Add react-hooks
compulim Nov 5, 2025
75b4309
Add Graph2
compulim Nov 5, 2025
5ffecc6
Add Graph2.middleware
compulim Nov 5, 2025
9ef8d52
Use Map for middleware
compulim Nov 5, 2025
8008d9c
Clean up
compulim Nov 5, 2025
d9aab0e
Support JSON literals
compulim Nov 5, 2025
8d1a72b
Update npm start dependencies
compulim Nov 5, 2025
9005f47
Activity as JSON literal
compulim Nov 5, 2025
a7c3a4e
Sort
compulim Nov 5, 2025
197b981
Test assumptions
compulim Nov 5, 2025
809f976
Clean up
compulim Nov 5, 2025
b475097
Fixed node reference
compulim Nov 5, 2025
4782887
Clean up schema
compulim Nov 5, 2025
9aba4e1
Add @see
compulim Nov 5, 2025
2dbb694
Add validation schema
compulim Nov 5, 2025
aa1c9ad
Move to SlantGraph
compulim Nov 5, 2025
9c1ebe2
Validate middleware result
compulim Nov 5, 2025
338865f
Validate middleware request/result
compulim Nov 5, 2025
670360e
Auto-inversing and no flatten node reference
compulim Nov 5, 2025
9d39b09
Update opinion text
compulim Nov 5, 2025
8bf7d07
npm start without transient local dependencies
compulim Nov 5, 2025
0f7c7e4
Deprecate Graph1
compulim Nov 5, 2025
c63740f
Reorganize files
compulim Nov 6, 2025
1bd0245
Clean up
compulim Nov 6, 2025
8121870
Clean up auto-inversion
compulim Nov 7, 2025
f6b2845
Add crypto.randomUUID
compulim Nov 7, 2025
0d22179
Fix randomUUID
compulim Nov 7, 2025
5c4e681
Hide console log
compulim Nov 7, 2025
1a73f32
Remove obsoleted Graph1
compulim Nov 7, 2025
92b4648
Clean up
compulim Nov 7, 2025
a8a446f
Ponyfill
compulim Nov 7, 2025
6f57585
Use uuid.v4()
compulim Nov 7, 2025
5a63e12
Handle event activity
compulim Nov 9, 2025
20977e2
Fix race condition on setOrderedActivities
compulim Nov 10, 2025
ec0a8d6
readonly activities[]
compulim Nov 10, 2025
7eb48c2
Skip test
compulim Nov 10, 2025
d1b67d1
Allow typing activity
compulim Nov 10, 2025
bcaf98c
Allow optional identifier
compulim Nov 10, 2025
820be3f
Fix freeze SlantNode
compulim Nov 10, 2025
491f88b
Fix initial subscribe not processing graph
compulim Nov 10, 2025
e1c0cd2
Fix duplicated line
compulim Nov 10, 2025
cb84eb5
Use sequence ID to sort, add webchat:internal:position
compulim Nov 11, 2025
664a744
Fix ESLint
compulim Nov 11, 2025
f27ee43
Graph to support replace activity
compulim Nov 11, 2025
c1b4eee
Fix replace activity for activity without ID
compulim Nov 11, 2025
7e80acc
Support replace activity with clientActivityId
compulim Nov 11, 2025
2b22862
Fix replacing undefined client activity ID
compulim Nov 11, 2025
07c8480
Add permanent ID
compulim Nov 11, 2025
2554543
Clean u9p
compulim Nov 11, 2025
ec17dc6
Add comment
compulim Nov 11, 2025
ca84d7f
Use uuid instead of crypto.randomUUID
compulim Nov 11, 2025
16ecbe8
Add new property to fix typing
compulim Nov 11, 2025
654466c
Assign random value if no activity.id
compulim Nov 11, 2025
e324661
Keep activity when receive echoback
compulim Nov 11, 2025
da0e41d
Keep outgoing pending activity at same position
compulim Nov 11, 2025
10e156f
Set outgoing pending with sequence ID instead of timestamp
compulim Nov 11, 2025
4149789
Fix sort fallback properly
compulim Nov 11, 2025
bd4dd96
Fix get timestamp of 0
compulim Nov 11, 2025
d6a7067
Trigger subscriber after transaction is closed
compulim Nov 11, 2025
ba22d00
Handle unknown activity type
compulim Nov 11, 2025
a544bcf
Add activity.id for dedupe while remount
compulim Nov 11, 2025
678a072
Allow activity.timestamp: undefined
compulim Nov 11, 2025
282c782
Ordering should not take account into activities without timestamp
compulim Nov 11, 2025
68b1600
Add snapshot
compulim Nov 11, 2025
33c6749
Fix ESLint
compulim Nov 11, 2025
e7fd412
Allow-warn timestamp of type Date
compulim Nov 11, 2025
6d09997
Allow act/upsert during subscribe() call
compulim Nov 11, 2025
a15ea19
Fix test
compulim Nov 11, 2025
86b4afd
Compare position
compulim Nov 11, 2025
5fa31ea
Add debugging
compulim Nov 12, 2025
fd8b545
Revert debugging
compulim Nov 12, 2025
9c81085
Assert with Redux
compulim Nov 12, 2025
c4cec3f
Clean up
compulim Nov 12, 2025
84ad788
Clean up
compulim Nov 12, 2025
f6cd272
Add freeze and clean up
compulim Nov 12, 2025
ae3eeca
Clean up
compulim Nov 12, 2025
b593eb5
Fix typing
compulim Nov 12, 2025
6478f45
Move freeze to base/valibot
compulim Nov 12, 2025
d0386e5
Typo
compulim Nov 12, 2025
0f6f4f0
Remove TODO
compulim Nov 12, 2025
8f96807
Add terminator middleware
compulim Nov 12, 2025
d88f3ac
Clean up
compulim Nov 12, 2025
17e0ad6
Fix assertion, clean ordered activities on remount
compulim Nov 12, 2025
c25355a
Clean up internal properties if passed in
compulim Nov 12, 2025
42c72bd
Rename to upserting from incoming
compulim Nov 12, 2025
3fde106
Clean up
compulim Nov 12, 2025
d878159
Clean up by removing compose()
compulim Nov 12, 2025
d24ce15
Merge branch 'main' into feat-graph
compulim Nov 12, 2025
e402703
Add entry
compulim Nov 12, 2025
55013d6
Extract and cache schema object
compulim Nov 12, 2025
850640c
Remove commented code
compulim Nov 12, 2025
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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,7 @@ Notes: web developers are advised to use [`~` (tilde range)](https://github.com/
- Cleaned up `<ThemeProvider>` and various CSS related code, in PR [#5611](https://github.com/microsoft/BotFramework-WebChat/pull/5611), by [@compulim](https://github.com/compulim)
- (Experimental) Reworked the copilot variant to align with the modern Copilot UX, in PR [#5630](https://github.com/microsoft/BotFramework-WebChat/pull/5630), by [@OEvgeny](https://github.com/OEvgeny)
- The legacy design is temporarily available as `copilot-deprecated` for migration
- New JSON-LD graph backend, by [@compulim](https://github.com/compulim) in PR [#5622](https://github.com/microsoft/BotFramework-WebChat/pull/5622)

### Changed

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
<!doctype html>
<html lang="en-US">
<head>
<link href="/assets/index.css" rel="stylesheet" type="text/css" />
</head>
<body>
<main id="webchat"></main>
<script type="importmap">
{
"imports": {
"botframework-webchat": "/__dist__/packages/bundle/static/botframework-webchat.js",
"react": "/__dist__/packages/bundle/static/react.js",
"react-dom": "/__dist__/packages/bundle/static/react-dom.js"
}
}
</script>
<script type="module">
import '/test-harness.mjs';
import '/test-page-object.mjs';

import { createDirectLine, createStoreWithOptions, renderWebChat } from 'botframework-webchat';
import { version } from 'react';

run(async function () {
const {
testHelpers: { createDirectLineEmulator }
} = window;

// TODO: This is for `createDirectLineEmulator` only, should find ways to eliminate this line.
window.WebChat = { createStoreWithOptions };

const { directLine, store } = createDirectLineEmulator();

renderWebChat({ directLine, store }, document.getElementById('webchat'));

await pageConditions.uiConnected();

const now = Date.now();

await directLine.emulateIncomingActivity({
from: { role: 'bot' },
text: '1 without timestamp.',
timestamp: undefined,
type: 'message'
});

await directLine.emulateIncomingActivity({
from: { role: 'bot' },
text: '2 with t = 0.',
timestamp: new Date(now).toISOString(),
type: 'message'
});

await directLine.emulateIncomingActivity({
from: { role: 'bot' },
text: '4 with t = 2.',
timestamp: new Date(now + 2).toISOString(),
type: 'message'
});

await directLine.emulateIncomingActivity({
from: { role: 'bot' },
text: '5 without timestamp.',
timestamp: undefined,
type: 'message'
});

await directLine.emulateIncomingActivity({
from: { role: 'bot' },
text: '3 with t = 1.',
timestamp: new Date(now + 1).toISOString(),
type: 'message'
});

expect(pageElements.activityContents().map(({ textContent }) => textContent)).toEqual([
'1 without timestamp.',
'2 with t = 0.',
'3 with t = 1.',
'4 with t = 2.',
'5 without timestamp.'
]);

await host.snapshot('local');
});
</script>
</body>
</html>
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
50 changes: 50 additions & 0 deletions __tests__/html2/activityOrdering/twoOutgoingMessage.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
<!doctype html>
<html lang="en-US">
<head>
<link href="/assets/index.css" rel="stylesheet" type="text/css" />
</head>
<body>
<main id="webchat"></main>
<script type="importmap">
{
"imports": {
"botframework-webchat": "/__dist__/packages/bundle/static/botframework-webchat.js",
"react": "/__dist__/packages/bundle/static/react.js",
"react-dom": "/__dist__/packages/bundle/static/react-dom.js"
}
}
</script>
<script type="module">
import '/test-harness.mjs';
import '/test-page-object.mjs';

import { createDirectLine, createStoreWithOptions, renderWebChat } from 'botframework-webchat';
import { version } from 'react';

run(async function () {
const {
testHelpers: { createDirectLineEmulator }
} = window;

// TODO: This is for `createDirectLineEmulator` only, should find ways to eliminate this line.
window.WebChat = { createStoreWithOptions };

const { directLine, store } = createDirectLineEmulator();

renderWebChat({ directLine, store }, document.getElementById('webchat'));

await pageConditions.uiConnected();

await directLine.emulateOutgoingActivity('One.');

await pageConditions.numActivitiesShown(1);

await directLine.emulateOutgoingActivity('Two.');

await pageConditions.numActivitiesShown(2);

expect(pageElements.activityContents().map(({ textContent }) => textContent)).toEqual(['One.', 'Two.']);
});
</script>
</body>
</html>
1 change: 1 addition & 0 deletions __tests__/html2/basic/remount.html
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
() =>
createDirectLineWithTranscript([
{
id: 'a-00001', // ID is needed to make sure activity is not added twice when remounted and resubscribed.
text: `Hello, World!`,
type: 'message',
timestamp: '2000-01-23T12:34:56.12345Z'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,8 @@
await pageObjects.sendMessageViaSendBox('User activity has timestamp of 1.', { waitForSend: false });
await pageObjects.sendMessageViaSendBox('User activity has timestamp of 0.', { waitForSend: false });

await pageConditions.numActivitiesShown(3);

const { activities } = store.getState();

// THEN: The first outgoing message should be the second, after the bot's message.
Expand All @@ -86,14 +88,16 @@
// THEN: The second outgoing message should be the third.
expect(activities[2].text).toBe('User activity has timestamp of 0.');

// THEN: The first outgoing message should have a smaller sequence ID than the bot's message.
// THEN: The first outgoing message should have a smaller position than the bot's message.
expect(
activities[0].channelData['webchat:sequence-id'] < activities[1].channelData['webchat:sequence-id']
activities[0].channelData['webchat:internal:position'] <
activities[1].channelData['webchat:internal:position']
).toBe(true);

// THEN: The first outgoing message should have a smaller sequence ID than the second outgoing message.
// THEN: The first outgoing message should have a smaller position than the second outgoing message.
expect(
activities[1].channelData['webchat:sequence-id'] < activities[2].channelData['webchat:sequence-id']
activities[1].channelData['webchat:internal:position'] <
activities[2].channelData['webchat:internal:position']
).toBe(true);

// THEN: Both outgoing messages should not send "webchat:sequence-id" and "state".
Expand Down
2 changes: 1 addition & 1 deletion __tests__/html2/part-grouping/position.html
Original file line number Diff line number Diff line change
Expand Up @@ -278,4 +278,4 @@
</script>
</body>

</html>
</html>
1 change: 1 addition & 0 deletions __tests__/html2/preact/activity/feedback.status.html
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@
);

await pageConditions.uiConnected();
await pageConditions.numActivitiesShown(3);

await host.snapshot('local');

Expand Down
11 changes: 11 additions & 0 deletions __tests__/setup/setupCryptoRandomUUID.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { v4 } from 'uuid';

// In browser, only works in secure context.
if (!global.crypto?.randomUUID) {
global.crypto = {
...global.crypto,
randomUUID() {
return v4();
}
};
}
3 changes: 3 additions & 0 deletions jest.legacy.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,14 +63,17 @@ module.exports = {
'<rootDir>/__tests__/setup/setupGlobalAgent.js',
'<rootDir>/__tests__/setup/preSetupTestFramework.js',
'<rootDir>/__tests__/setup/setupCryptoGetRandomValues.js',
'<rootDir>/__tests__/setup/setupCryptoRandomUUID.js',
'<rootDir>/__tests__/setup/setupImageSnapshot.js',
'<rootDir>/__tests__/setup/setupTestNightly.js',
'<rootDir>/__tests__/setup/setupTimeout.js'
],
testMatch: ['**/__tests__/**/*.?([mc])[jt]s?(x)', '**/?(*.)+(spec|test).?([mc])[jt]s?(x)'],
testPathIgnorePatterns: [
'/dist/',
'/lib/',
'/node_modules/',
'/static/',
'<rootDir>/__tests__/html/.*?(\\.html)',
'<rootDir>/__tests__/html/__dist__',
'<rootDir>/__tests__/html/__jest__',
Expand Down
1 change: 1 addition & 0 deletions lint-staged.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ module.exports = {
'**/*.md': prettierMarkdown,
'packages/**/*.css': ['npm run precommit:biome'],
'packages/api/src/**/*.{mjs,js,ts,tsx}': ['npm run precommit:eslint:api'],
'packages/api-graph/src/**/*.{mjs,js,ts,tsx}': ['npm run precommit:eslint:api-graph'],
'packages/api-middleware/src/**/*.{mjs,js,ts,tsx}': ['npm run precommit:eslint:api-middleware'],
'packages/base/src/**/*.{mjs,js,ts,tsx}': ['npm run precommit:eslint:base'],
'packages/bundle/src/**/*.{mjs,js,ts,tsx}': ['npm run precommit:eslint:bundle'],
Expand Down
Loading
Loading