Skip to content

feat(client): [internal] container extensions and presence use #24399

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
c207f58
feat(client-container-runtime): path-based address signal routing
jason-ha Apr 16, 2025
8b219d7
improvement(client): use generic for signal content
jason-ha Apr 13, 2025
1872d87
feat(client): internal container extensions interface
jason-ha Apr 16, 2025
62d3fa6
improvement(client): enhance and tighten types for container extensio…
jason-ha Apr 17, 2025
b1f8232
improvement(client): distinguish raw incoming signals
jason-ha Apr 17, 2025
112853b
feat(client): implement internal container extensions support
jason-ha Apr 17, 2025
11c4a19
docs(client-container-definitions): comments for `IRuntimeInternal`
jason-ha Apr 25, 2025
f2e7304
improvement(client-container-loader): replace `as` with typed target
jason-ha Apr 25, 2025
beb23e2
improvement(client-example): use URLSearchParams
jason-ha Apr 25, 2025
ce07bf4
merge: 'main' into presence/infra/support-path-based-address-routing-…
jason-ha Apr 25, 2025
a7e847b
merge: 'main' into presence/infra/support-path-based-address-routing-…
jason-ha May 20, 2025
2f3b12e
refactor(client): remove ContainerExtensionStore from container (load…
jason-ha May 22, 2025
b0d8db2
feat(client): declarative Presence support
jason-ha May 22, 2025
1c4be86
style(client-container-runtime): restore implements ordering
jason-ha May 22, 2025
98b0e92
revert(client-container-runtime): remove dark pathBasedAddressing run…
jason-ha May 22, 2025
f1c3bea
docs(client-presence): `getPresence` now supported
jason-ha May 22, 2025
d92548a
style(client): renames and comments
jason-ha May 23, 2025
a6ad229
refactor(client): generics ordering
jason-ha May 23, 2025
46fa5bf
merge: 'main' into presence/infra/support-path-based-address-routing-…
jason-ha May 23, 2025
5b1ed99
refactor(client-container-runtime): simplify addressed path support
jason-ha May 23, 2025
41cfcc6
build(client-presence): remove unused container-loader dep
jason-ha May 23, 2025
ce572d1
test(client-examples): cleanup deprecated presence init
jason-ha May 23, 2025
1d0fddd
fix(client-fluid-static): fix breaks from merge
jason-ha May 23, 2025
75001bd
merge: 'main' into presence/infra/support-path-based-address-routing-…
jason-ha May 23, 2025
7ec1564
fix(client-example): correct for fluid-static changes
jason-ha May 23, 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
8 changes: 8 additions & 0 deletions .changeset/wet-towns-ask.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
"@fluidframework/container-runtime": minor
"__section": feature
---

Introduce path based message routing

Add ability for runtime to address messages with a `/` separated path scheme. `/runtime/` is reserved for runtime where `undefined` was previously used and data store messages are prefixed with `/channels/`. To enable general sending messages with this scheme, internal `IContainerRuntimeOptionsInternal.pathBasedAddressing` must be enabled. Internally `presence` requires this support under the `/ext/` path and thus should only be used once involved clients are using version 2.33 or later.
19 changes: 5 additions & 14 deletions docs/docs/build/presence.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@ sidebar_postition: 10

## Overview

We are introducting a new way to power your ephemeral experiences wth Fluid. Introducing the new Presence APIs (currently in alpha) that provide session-focused utilities for lightweight data sharing and messaging.

We are introducing a new way to power your ephemeral experiences with Fluid. Introducing the new Presence APIs (currently in alpha) that provide session-focused utilities for lightweight data sharing and messaging.
Collaborative features typically rely on each user maintaining their own temporary state, which is subsequently shared with others. For example, in applications featuring multiplayer cursors, the cursor position of each user signifies their state. This state can be further utilized for various purposes such as indicating typing activity or displaying a user's current selection. This concept is referred to as _presence_.

By leveraging this shared state, applications can provide a seamless and interactive collaborative experience, ensuring that users are always aware of each other's actions and selections in real-time.
Expand Down Expand Up @@ -57,21 +56,13 @@ Notifications are special case where no data is retained during a session and al

## Onboarding

While this package is developing as experimental and other Fluid Framework internals are being updated to accommodate it, a temporary Shared Object must be added within container to gain access.
To access Presence APIs, use `getPresence()` with any `IFluidContainer`.

```typescript
import {
getPresenceViaDataObject,
ExperimentalPresenceManager,
} from "@fluidframework/presence/alpha";

const containerSchema = {
initialObjects: {
presence: ExperimentalPresenceManager,
},
} satisfies ContainerSchema;
import { getPresence } from "@fluidframework/presence/alpha";

const presence = await getPresenceViaDataObject(container.initialObjects.presence);
function usePresence(container: IFluidContainer): void {
const presence = await getPresence(container);
```

## Limitations
Expand Down
16 changes: 12 additions & 4 deletions examples/apps/presence-tracker/src/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
*/

import {
getPresence,
getPresenceViaDataObject,
ExperimentalPresenceManager,
} from "@fluidframework/presence/alpha";
Expand All @@ -16,10 +17,14 @@ import { initializeReactions } from "./reactions.js";
import { renderControlPanel, renderFocusPresence, renderMousePresence } from "./view.js";

// Define the schema of the Fluid container.
// This example uses the presence features only, so only that data object is added.
// This example uses the presence features only, so no data object is required.
// But the old experimental presence data object is used to check that old path still works.
// Besides initialObjects is not currently allowed to be empty.
// That version of presence is compatible with all 2.x runtimes. Long-term support without
// data object requires 2.32 or later.
const containerSchema = {
initialObjects: {
// A Presence Manager object temporarily needs to be placed within container schema
// A Presence Manager object placed within container schema for experimental presence access
// https://github.com/microsoft/FluidFramework/blob/main/packages/framework/presence/README.md#onboarding
presence: ExperimentalPresenceManager,
},
Expand Down Expand Up @@ -56,8 +61,11 @@ async function start() {
({ container } = await client.getContainer(id, containerSchema, "2"));
}

// Retrieve a reference to the presence APIs via the data object.
const presence = getPresenceViaDataObject(container.initialObjects.presence);
const useDataObject = location.search.includes("useDataObject");
const presence = useDataObject
? // Retrieve a reference to the presence APIs via the data object.
getPresenceViaDataObject(container.initialObjects.presence)
: getPresence(container);

// Get the states workspace for the tracker data. This workspace will be created if it doesn't exist.
// We create it with no states; we will pass the workspace to the Mouse and Focus trackers, and they will create value
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,7 @@ import {
} from "@fluidframework/azure-client";
import { createDevtoolsLogger, initializeDevtools } from "@fluidframework/devtools/beta";
import { ISharedMap, IValueChanged, SharedMap } from "@fluidframework/map/legacy";
import {
getPresenceViaDataObject,
ExperimentalPresenceManager,
} from "@fluidframework/presence/alpha";
import { getPresence } from "@fluidframework/presence/alpha";
import { createChildLogger } from "@fluidframework/telemetry-utils/legacy";
// eslint-disable-next-line import/no-internal-modules -- #26985: `test-runtime-utils` internal used in example
import { InsecureTokenProvider } from "@fluidframework/test-runtime-utils/internal";
Expand Down Expand Up @@ -76,9 +73,6 @@ const containerSchema = {
/* [id]: DataObject */
map1: SharedMap,
map2: SharedMap,
// A Presence Manager object temporarily needs to be placed within container schema
// https://github.com/microsoft/FluidFramework/blob/main/packages/framework/presence/README.md#onboarding
presence: ExperimentalPresenceManager,
},
} satisfies ContainerSchema;
type DiceRollerContainerSchema = typeof containerSchema;
Expand Down Expand Up @@ -182,7 +176,7 @@ async function start(): Promise<void> {

// Biome insist on no semicolon - https://dev.azure.com/fluidframework/internal/_workitems/edit/9083
const lastRoll: { die1?: DieValue; die2?: DieValue } = {};
const presence = getPresenceViaDataObject(container.initialObjects.presence);
const presence = getPresence(container);
const states = buildDicePresence(presence).states;

// Initialize Devtools
Expand Down
Loading
Loading