github microsoft/FluidFramework client_v3.7.0
Fluid Framework v3.7.0 (minor)

3 hours ago

Contents

  • 🌳 SharedTree DDS Changes
    • Reduce the bundle size of schema hashing (#28496)
    • Simplify the alpha schema identity API (#28496)
    • Unsafe array-to-tuple conversion is available for allowed schemas (#28502)
    • Adds debug-only checks to facilitate root cause analysis of SharedTree bugs (#28435)
    • Slightly faster SharedTree initialization (#28527)
    • Use stable definition ordering in schema exports (#28544)
    • Configure how much SharedTree edit history to retain (#28511)
  • 🐛 Bug Fixes
    • Binary summary blob contents can no longer include neighboring bytes in Node.js when a Buffer is a view into a larger allocation (#28485)
    • Container dirty state now accounts for outstanding attachment blob work (#28459)
    • Devtools ignores messages from other windows (#28503)
    • Containers passed to startTelemetry are no longer kept in memory after they are disposed (#28515)
    • TreeArrayNodes correctly handle null elements during iteration and removal (#28519)

🌳 SharedTree DDS Changes

Reduce the bundle size of schema hashing (#28496)

Schema hashing uses a browser-oriented SHA-256 implementation without Node.js Buffer compatibility dependencies. This reduces browser bundle size when using identifySchemaAlpha.

Change details

Commit: c98cc8b

Affected packages:

  • @fluidframework/tree
  • fluid-framework

⬆️ Table of contents

Simplify the alpha schema identity API (#28496)

The alpha identifySchema function is renamed to identifySchemaAlpha. The alpha computeSchemaHash function is no longer exported. To check a schema against an expected hash, pass a schema identity to the view configuration:

const config = new TreeViewConfigurationAlpha({
  schema: MySchema,
  schemaIdentity: identifySchemaAlpha({ expectedHash: savedHash }),
});

If the expected hash does not match, the view construction error includes the actual hash.

Change details

Commit: c98cc8b

Affected packages:

  • @fluidframework/tree
  • fluid-framework

⬆️ Table of contents

Unsafe array-to-tuple conversion is available for allowed schemas (#28502)

The alpha API unsafeArrayToTuple is now exported from @fluidframework/tree/alpha and fluid-framework/alpha. It returns the original array with its type converted using UnionToTuple, allowing insertable content APIs to work when tuple type information has been lost. Prefer preserving the tuple type with as const when possible. The helper does not validate the array: if its element type includes a schema that is absent at runtime, TypeScript can accept content that fails at runtime.

See Why is my insertable content getting typed as never? for examples and an explanation of the runtime risks.

Change details

Commit: 1b88709

Affected packages:

  • @fluidframework/tree
  • fluid-framework

⬆️ Table of contents

Adds debug-only checks to facilitate root cause analysis of SharedTree bugs (#28435)

This version adds additional runtime checks to detect errors in the rebasing (commit merging) layer. These checks can be used by application authors when faced with a SharedTree rebasing bug. For example:

import { RebaseValidation } from "@fluidframework/tree/alpha";

it("repro SharedTree bug", () => {
  // Reproduce the SharedTree bug under strict rebase validation level.
  RebaseValidation.runWithLevel(RebaseValidation.Level.Strict, () => {
    // Buggy scenario
    // ...
  });
});

Running the test with strict validation is more likely to yield actionable feedback for SharedTree maintainers.

These checks are tree-shaken out of production builds, so they have no impact on shipped applications.

There are three levels of checking available:

  • RebaseValidation.Level.None: No rebase validation is performed.
  • RebaseValidation.Level.Cheap: A minimal amount of rebase validation is performed, with minimal performance overhead.
  • RebaseValidation.Level.Strict: Extensive rebase validation is performed, with the highest performance overhead.

The level is set to RebaseValidation.Level.Cheap by default. Debug builds may therefore experience asserts in scenarios where they did not before. The level can be adjusted by calling RebaseValidation.setLevel or RebaseValidation.runWithLevel.

Change details

Commit: 2e08a3a

Affected packages:

  • fluid-framework
  • @fluidframework/tree

⬆️ Table of contents

Slightly faster SharedTree initialization (#28527)

TreeView.initialize() is now slightly faster for large schemas when debug-only checks are disabled or optimized out. See non-production conditional code for details on how bundlers remove these checks from production builds.

For a synthetic schema with 240 object types and 1,200 fields (five fields per object type), plus an array root allowing all 240 types, warm initialization took about 7% less time in a local benchmark:

Measurement Before After
TreeView.initialize([]) 5.21 ms 4.83 ms

The tree was initialized with an empty array: these numbers measure schema-related initialization work, not loading 240 objects. Measurements used Node.js with debug-only checks disabled and exclude view creation. Results depend on the schema and environment.

Change details

Commit: 7402252

Affected packages:

  • @fluidframework/tree
  • fluid-framework

⬆️ Table of contents

Use stable definition ordering in schema exports (#28544)

SharedTree JSON Schema exports and schema compatibility snapshots now write node definitions in a stable identifier order, independent of definition map insertion order and locale. Field and allowed-type ordering is unchanged.

Newly generated output may differ in definition ordering from older output. Existing compatibility snapshots remain usable without regeneration, and ordering alone does not change schema compatibility results. Schema hashes and persisted schema encoding are unchanged.

Change details

Commit: 30b0ce8

Affected packages:

  • @fluidframework/tree
  • fluid-framework

⬆️ Table of contents

Configure how much SharedTree edit history to retain (#28511)

The existing alpha SharedTree retainHistory option now accepts a number in addition to a boolean. Pass a nonnegative safe integer to retain the newest specified number of available sequenced main-branch commits, true to retain all available history, or false or 0 to disable extra retention.

import { configuredSharedTree } from "fluid-framework/alpha";

const SharedTree = configuredSharedTree({ retainHistory: 20 });

Collaboration and existing branches can require retaining more commits than the configured number. After loading a summary, trimming waits for the collaboration boundary to be reported. The count applies to sequenced commits, not file versions or snapshots. The policy is local to each SharedTree instance and is not persisted or sent to other clients. History that has already been removed cannot be recovered by increasing retention.

The existing boolean behavior is unchanged, and omitting retainHistory still defaults to false.

Change details

Commit: 9c5a7cc

Affected packages:

  • @fluidframework/tree
  • fluid-framework

⬆️ Table of contents

🐛 Bug Fixes

Binary summary blob contents can no longer include neighboring bytes in Node.js when a Buffer is a view into a larger allocation (#28485)

In Node.js, binary summary blob content provided as a Buffer which covered only part of its underlying memory could be converted into an ArrayBuffer containing the underlying memory rather than just the blob's bytes. For example: a small pooled Buffer or the result of subarray. This affected snapshots produced from detached container summaries and files created via the ODSP driver from a detached summary, and could result in extra or unrelated bytes being stored with a blob.

Only the bytes belonging to the blob are now included. Browser environments were not affected.

Change details

Commit: c3f918b

Affected packages:

  • @fluidframework/container-loader
  • @fluidframework/odsp-driver

⬆️ Table of contents

Container dirty state now accounts for outstanding attachment blob work (#28459)

IContainer.isDirty and IFluidContainer.isDirty now include outstanding attachment blob work, not just operations. Previously, saved could fire during a blob upload, allowing hosts to dispose the container and lose the attachment. Do not dispose a container while isDirty is true.

Blob work ends when sharing succeeds, fails, or is cancelled. The saved event means no local work remains outstanding, not that every blob was shared successfully. Failed or cancelled handles may remain unusable; observe the handle's payloadShared and payloadShareFailed events for individual outcomes.

container.on("saved", () => container.dispose());

Helpers waiting for saved now also wait for blob sharing to end. A stalled upload can keep them waiting indefinitely.

Blob coverage requires @fluidframework/container-loader from this release or later. Older loaders retain operation-only tracking; service clients such as @fluidframework/azure-client include a matching loader. Setting the runtime configuration flag Fluid.ContainerRuntime.DisableBlobAwareDirtyState to true restores operation-only dirty tracking. With either fallback, saved can fire while blob work remains outstanding.

Change details

Commit: b94b1f3

Affected packages:

  • @fluidframework/container-definitions
  • @fluidframework/container-runtime
  • @fluidframework/fluid-static
  • fluid-framework

⬆️ Table of contents

Devtools ignores messages from other windows (#28503)

Devtools now accepts window messages only from the application's own window. This prevents other windows from directly issuing devtools commands through window messaging.

Change details

Commit: e4a2759

Affected packages:

  • @fluidframework/devtools-core

⬆️ Table of contents

Containers passed to startTelemetry are no longer kept in memory after they are disposed (#28515)

Previously, startTelemetry started a heartbeat timer that was never stopped. That timer kept the container, along with its telemetry producer and consumers, in memory for the lifetime of the process, even after the container was disposed. In Node.js, it also stopped the process from exiting. The heartbeat timer now stops when the container is disposed.

Change details

Commit: 917bf63

Affected packages:

  • @fluidframework/fluid-telemetry

⬆️ Table of contents

TreeArrayNodes correctly handle null elements during iteration and removal (#28519)

Null elements in a TreeArrayNode are now handled correctly during iteration and by the alpha splice method. Previously, encountering a null element during iteration or removing one with splice incorrectly threw an out-of-bounds error.

Change details

Commit: 8defa17

Affected packages:

  • @fluidframework/tree
  • fluid-framework

⬆️ Table of contents

🛠️ Start Building Today!

Please continue to engage with us on GitHub Discussion and Issue pages as you adopt Fluid Framework!

Don't miss a new FluidFramework release

NewReleases is sending notifications on new releases.