npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@microsoft/fabric-app-data

v1.1.0

Published

Fabric Apps - Analytics SDK — auth-agnostic client for Semantic Models, Lakehouses, and Warehouses

Readme

@microsoft/fabric-app-data

Auth-agnostic SDK for querying Fabric Semantic Models, Lakehouses, and Warehouses

Quick Reference

Package: @microsoft/fabric-app-data Purpose: Auth-agnostic SDK for querying Fabric Semantic Models, Lakehouses, and Warehouses. Use when: You need to query data from Microsoft Fabric. This is the core SDK — it handles client creation, query execution, result caching, and error handling. Do NOT use when: You need a proxy implementation — use @microsoft/fabric-app-data-cli-proxy (Node.js local dev) or @microsoft/fabric-app-data-proxy (embedded iframe). This package requires one of those proxies to function. Key exports: FabricClient, SemanticModelClient, IFabricApiProxy, QueryResult, CachedQueryResult, FabricProxyError Peer dependencies: None (but requires an IFabricApiProxy implementation at runtime) Install: npm install @microsoft/fabric-app-data

Ecosystem Context

@microsoft/fabric-app-data is the core SDK package for Fabric Apps - Analytics. It defines the client classes, query/result types, proxy contracts, and proxy error contract, but it does not perform auth or HTTP/TDS transport itself.

You must inject an IFabricApiProxy implementation:

  • @microsoft/fabric-app-data-cli-proxy — local development and testing; calls Fabric APIs directly from Node.js with a token provider
  • @microsoft/fabric-app-data-proxy — embedded scenarios; forwards calls through postMessage via the embed client/iframe boundary

It is typically used alongside:

  • @microsoft/fabric-visuals — render semantic-model query results as Vega/Vega-Lite visuals
  • @microsoft/fabric-datagrid — render the same tabular results in a grid

Installation

npm install @microsoft/fabric-app-data

Public API

Client classes

FabricClient

export class FabricClient {
    constructor(config: FabricClientConfig);
    semanticModel(alias: string): SemanticModelClient;
    clearCache(): void;
}

Notes:

  • semanticModel(alias) returns a cached SemanticModelClient instance for the alias.
  • FabricClientConfig.semanticModels is currently consumed by the exported client API.
  • FabricConfig and IFabricApiProxy already define lakehouse and warehouse contracts for proxy implementations.
  • daxProtocol defaults to "json".

SemanticModelClient

export class SemanticModelClient {
    constructor(
        alias: string,
        ref: FabricItemRef,
        daxExecutor: DaxExecutor,
        cacheStore: QueryCacheStore | null,
        protocol: DaxProtocol,
    );

    query(dax: string, options?: QueryCacheOptions): Promise<CachedQueryResult>;
    clearCache(): void;
}

Notes:

  • In normal usage, obtain this class from fabric.semanticModel(alias).
  • query() selects Arrow vs JSON from the parent FabricClient's daxProtocol.
  • query() returns a result object and does not throw for query/API/network failures.

Types and interfaces

Connection model

export type WorkspaceId = "me" | (string & {});
export interface FabricItemRef {
    workspaceId: WorkspaceId;
    itemId: string;
}
export interface FabricConfig {
    semanticModels?: Record<string, FabricItemRef>;
    lakehouses?: Record<string, FabricItemRef>;
    warehouses?: Record<string, FabricItemRef>;
}
export type DaxProtocol = "arrow" | "json";
export interface FabricClientConfig extends FabricConfig {
    proxy: IFabricApiProxy;
    cache?: QueryCacheConfig;
    daxProtocol?: DaxProtocol;
}

Proxy contracts

export interface DaxProxyResponse {
    data: ArrayBuffer;
    requestId: string;
}
export interface DaxJsonProxyResponse {
    data: unknown;
    requestId: string;
}
export interface SqlProxyResponse {
    columns: Array<{ name: string; dataType: string }>;
    rows: unknown[][];
    requestId: string;
}
export interface ISemanticModelApiProxy {
    executeDax(
        workspaceId: WorkspaceId,
        itemId: string,
        query: string,
        options?: DaxQueryOptions,
    ): Promise<DaxProxyResponse>;

    executeDaxJson(
        workspaceId: WorkspaceId,
        itemId: string,
        query: string,
    ): Promise<DaxJsonProxyResponse>;
}
export interface ILakehouseApiProxy {
    executeSql(
        workspaceId: WorkspaceId,
        itemId: string,
        sql: string,
        params?: SqlParameters,
        options?: SqlQueryOptions,
    ): Promise<SqlProxyResponse>;
}
export interface IWarehouseApiProxy {
    executeSql(
        workspaceId: WorkspaceId,
        itemId: string,
        sql: string,
        params?: SqlParameters,
        options?: SqlQueryOptions,
    ): Promise<SqlProxyResponse>;
}
export interface IFabricApiProxy {
    semanticModel: ISemanticModelApiProxy;
    lakehouse: ILakehouseApiProxy;
    warehouse: IWarehouseApiProxy;
}

Query and cache types

export interface DaxQueryOptions {
    culture?: string;
    schemaOnly?: boolean;
    queryTimeout?: number;
    resultSetRowCountLimit?: number;
}
export interface QueryColumn {
    name: string;
    dataType: string;
}
export interface QueryTable {
    columns: QueryColumn[];
    rows: unknown[][];
}
export interface QueryError {
    category: "api" | "query" | "network" | "overflow" | "unknown";
    message: string;
    code?: string;
    details?: string;
}
export type QueryResult =
    | { status: "success"; table: QueryTable; requestId: string }
    | { status: "error"; error: QueryError; requestId: string };
export type CachedQueryResult = QueryResult & {
    fromCache: boolean;
    cachedAt?: Date;
};
export interface QueryCacheOptions {
    bypassCache?: boolean;
}
export interface QueryCacheConfig {
    maxEntries?: number;
    enabled?: boolean;
}
export interface SqlQueryOptions {
    queryTimeout?: number;
}
export type SqlParameters = Record<string, string | number | boolean | null>;

Error types

export type FabricProxyError =
    | FabricApiProxyError
    | FabricNetworkProxyError
    | FabricGenericProxyError;
export class FabricApiProxyError extends Error {
    readonly status: number;
    readonly requestId: string;
    readonly sessionId: string;
    readonly body: string;

    constructor(opts: {
        status: number;
        requestId: string;
        sessionId: string;
        body: string;
        message?: string;
    });
}
export class FabricNetworkProxyError extends Error {
    readonly requestId: string;
    readonly sessionId: string;
    readonly details: string;
    readonly cause?: unknown;

    constructor(opts: {
        requestId: string;
        sessionId: string;
        message: string;
        details?: string;
        cause?: unknown;
    });
}
export class FabricGenericProxyError extends Error {
    readonly requestId?: string;
    readonly sessionId?: string;
    readonly cause?: unknown;

    constructor(opts: {
        message: string;
        requestId?: string;
        sessionId?: string;
        cause?: unknown;
    });
}

Protocol and contract behavior

These behavior contracts are public even where the implementation classes are internal:

  • IFabricApiProxy.semanticModel.executeDax() returns Arrow IPC bytes in DaxProxyResponse.data
  • IFabricApiProxy.semanticModel.executeDaxJson() returns raw executeQueries JSON in DaxJsonProxyResponse.data
  • SemanticModelClient.query() chooses which proxy method to call from FabricClientConfig.daxProtocol
  • Arrow responses are parsed in-package, including LZ4-compressed Arrow streams

QueryResult may be an error — always check status

query() returns a QueryResult discriminated union. Query failures, API errors, and network errors are returned as { status: "error" } rather than thrown — so you must always check result.status.

// ✅ DO: Always check result.status — it may be an error
const result = await fabric.semanticModel("sales").query("EVALUATE ...");
if (result.status === "success") {
    console.log(result.table.rows);
} else {
    // result.status === "error"
    // result.error.category is one of:
    //   "query"    — DAX syntax or semantic error
    //   "api"      — Fabric service rejected the request
    //   "network"  — fetch failed, timed out, or connection was lost
    //   "overflow" — numeric value exceeded safe JS precision
    //   "unknown"  — unrecognized failure
    console.error(result.error.category, result.error.message);
}

// ❌ DON'T: Assume a returned result is successful without checking status

Key Constraints & Gotchas

A proxy is always required

// ✅ DO: Always provide a proxy implementation
import { FabricClient } from "@microsoft/fabric-app-data";
import { DirectFabricApiProxy } from "@microsoft/fabric-app-data-cli-proxy";
const fabric = new FabricClient({ proxy: new DirectFabricApiProxy(tokenProvider), semanticModels: { ... } });

// ❌ DON'T: Try to create a FabricClient without a proxy
const fabric = new FabricClient({ semanticModels: { ... } }); // Error: proxy is required

Current exported client surface is semantic-model focused: FabricConfig and IFabricApiProxy include lakehouse and warehouse contracts, but the exported FabricClient currently exposes semanticModel(alias) only.

Check result.status instead of try/catch

// ✅ DO: Check the discriminated union
const result = await fabric.semanticModel("sales").query("EVALUATE ...");
if (result.status === "success") {
    console.log(result.table.rows);
} else {
    console.error(result.error.category, result.error.message);
}

// ❌ DON'T: Wrap in try/catch expecting thrown errors
try {
    const result = await fabric.semanticModel("sales").query("EVALUATE ...");
} catch (e) { /* query() does not throw for query/API/network failures */ }

JSON is the default DAX protocol

// ✅ DO: Explicitly set daxProtocol if you want Arrow
const fabric = new FabricClient({ proxy, daxProtocol: "arrow", semanticModels: { ... } });

// Default behavior (no daxProtocol) uses "json"

Results are single-table

  • Each query() call executes one EVALUATE statement and returns one table.
  • result.table (not result.tables) contains { columns: QueryColumn[], rows: unknown[][] }.
  • The success payload is already in the same row-major columns + rows shape used across the visuals stack, so result.table can feed rendering pipelines built around @microsoft/fabric-visuals-core/@microsoft/fabric-datagrid.

Cache behavior

  • Results are cached in-memory by default (LRU, max 64 entries).
  • Cache keys are derived from (alias, query, protocol, options).
  • bypassCache: true skips reading from cache but still writes the fresh result to cache.
  • Only "success" and "query" errors are cached; "api", "network", "unknown" errors are not.
  • fabric.clearCache() clears all aliases; fabric.semanticModel("x").clearCache() clears only that alias.

Arrow vs JSON type fidelity

  • Arrow: typed columns (Int64, Double, Decimal, Boolean, String, DateTime). Int64/Decimal → number, Date/DateTime → ISO string without trailing Z.
  • JSON: all columns have dataType: "unknown" because the legacy endpoint lacks type metadata.
  • Unsafe numeric overflows return error.category === "overflow" instead of corrupting data.

workspaceId supports My Workspace

// ✅ Both are valid
{ workspaceId: "me", itemId: "..." }           // My Workspace
{ workspaceId: "guid-here", itemId: "..." }    // Named workspace

Minimal Usage Examples

Create a client with an injected proxy

import { FabricClient, type IFabricApiProxy } from "@microsoft/fabric-app-data";

declare const proxy: IFabricApiProxy;

const fabric = new FabricClient({
    proxy,
    semanticModels: {
        sales: {
            workspaceId: "me",
            itemId: "00000000-0000-0000-0000-000000000000",
        },
    },
});

Run a semantic-model query

const result = await fabric.semanticModel("sales").query("EVALUATE ROW(\"x\", 1)");

if (result.status === "success") {
    console.log(result.table.columns);
    console.log(result.table.rows);
} else {
    console.error(result.error.category, result.error.message);
}

Opt into Arrow and bypass cache for a fresh read

const fabric = new FabricClient({
    proxy,
    daxProtocol: "arrow",
    semanticModels: {
        sales: { workspaceId: "me", itemId: "00000000-0000-0000-0000-000000000000" },
    },
});

const fresh = await fabric.semanticModel("sales").query("EVALUATE ROW(\"x\", 1)", {
    bypassCache: true,
});

Trademarks

This project may contain trademarks or logos for projects, products, or services. Authorized use of Microsoft trademarks or logos is subject to and must follow Microsoft's Trademark & Brand Guidelines. Use of Microsoft trademarks or logos in modified versions of this project must not cause confusion or imply Microsoft sponsorship. Any use of third-party trademarks or logos are subject to those third-party's policies.

Security

Microsoft takes the security of our software products and services seriously, which includes all source code repositories in our GitHub organizations.

Please do not report security vulnerabilities through public GitHub issues.

For security reporting information, locations, contact information, and policies, please review the latest guidance for Microsoft repositories at https://aka.ms/SECURITY.md.

Code of conduct

We as members, contributors, and leaders pledge to make participation in our community a harassment-free experience for everyone, regardless of age, body size, visible or invisible disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, caste, color, religion, or sexual identity and orientation.

We pledge to act and interact in ways that contribute to an open, welcoming, diverse, inclusive, and healthy community.

See full Microsoft Open Source Code of Conduct