diff --git a/CHANGELOG.md b/CHANGELOG.md
index ce05e63..62aabb2 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## Unreleased
+### Added
+
+- Preview a single-file data app locally with `altertable app dev --file index.tsx`. The file's `defineDataApp` scope must match the selected profile, and queries run through the CLI's loopback proxy.
+
### Fixed
- Complete stdin-based credential configuration before exiting on Windows.
@@ -24,6 +28,8 @@ If credentials were saved inside a project, sign in again after upgrading and re
### Changed
+- Use the published 0.72.0 manifest extractor and Bun preview server for single-file data app development; align starter and browser-test packages at 0.72.0.
+
- Generate data apps with the split core, React, and Bun packages at 0.71.0; keep declared data-app packages aligned during upgrades.
- Update generated data apps and fixtures to `@altertable/data-app` 0.69.0.
diff --git a/COMMANDS.md b/COMMANDS.md
index 89f01b2..a3d47ee 100644
--- a/COMMANDS.md
+++ b/COMMANDS.md
@@ -423,7 +423,7 @@ altertable app create|dev|build|lint|upgrade|validate|publish|update
**Subcommands**
- `create` — Create a local data app project with a live connection check.
-- `dev` — Preview a data app locally with lakehouse access.
+- `dev` — Preview a local data app directory, or a single-file data app, with lakehouse access.
- `build` — Typecheck and build a local data app without Altertable credentials.
- `lint` — Lint a local data app project: format, lint rules, types, contracts, build, and client credential boundary.
- `upgrade` — Update a local data app's package to the CLI's tested version.
@@ -436,6 +436,7 @@ altertable app create|dev|build|lint|upgrade|validate|publish|update
```bash
altertable app create my-app
altertable app dev
+altertable app dev --file index.tsx
altertable app lint
altertable app build
altertable app upgrade
@@ -477,7 +478,7 @@ altertable --profile production app create product-pulse
#### `altertable app dev`
-Preview a data app locally with lakehouse access.
+Preview a local data app directory, or a single-file data app, with lakehouse access.
**Usage**
@@ -490,7 +491,8 @@ altertable app dev [options]
| Option | Description |
| --- | --- |
| `--dir
` | App directory (default: current directory). |
-| `--port ` | Local dev server port (1–65535; default: app setting). |
+| `--file ` | Path to a single-file React data app (index.tsx) to preview instead of --dir. Queries are declared in the file via defineDataApp. |
+| `--port ` | Local dev server port (1–65535; default: app setting, or 25837 for --file). |
**Examples**
@@ -498,6 +500,7 @@ altertable app dev [options]
altertable app dev
altertable app dev --port 3022
altertable --profile staging app dev --dir ./my-app
+altertable app dev --file ./index.tsx
```
#### `altertable app build`
diff --git a/cli-reference.json b/cli-reference.json
index a5a47f3..20d685b 100644
--- a/cli-reference.json
+++ b/cli-reference.json
@@ -823,6 +823,7 @@
"examples": [
"altertable app create my-app",
"altertable app dev",
+ "altertable app dev --file index.tsx",
"altertable app lint",
"altertable app build",
"altertable app upgrade",
@@ -884,7 +885,7 @@
{
"id": "altertable-app-dev",
"command": "altertable app dev",
- "description": "Preview a data app locally with lakehouse access.",
+ "description": "Preview a local data app directory, or a single-file data app, with lakehouse access.",
"usage": [
"altertable app dev [options]"
],
@@ -901,11 +902,21 @@
"scope": "command",
"values": []
},
+ {
+ "name": "file",
+ "aliases": [],
+ "type": "string",
+ "description": "Path to a single-file React data app (index.tsx) to preview instead of --dir. Queries are declared in the file via defineDataApp.",
+ "required": false,
+ "repeatable": false,
+ "scope": "command",
+ "values": []
+ },
{
"name": "port",
"aliases": [],
"type": "string",
- "description": "Local dev server port (1–65535; default: app setting).",
+ "description": "Local dev server port (1–65535; default: app setting, or 25837 for --file).",
"required": false,
"repeatable": false,
"scope": "command",
@@ -915,7 +926,8 @@
"examples": [
"altertable app dev",
"altertable app dev --port 3022",
- "altertable --profile staging app dev --dir ./my-app"
+ "altertable --profile staging app dev --dir ./my-app",
+ "altertable app dev --file ./index.tsx"
],
"subcommands": []
},
diff --git a/cli/bun.lock b/cli/bun.lock
index f8bd11d..7a112f1 100644
--- a/cli/bun.lock
+++ b/cli/bun.lock
@@ -5,6 +5,7 @@
"": {
"name": "cli",
"dependencies": {
+ "@altertable/data-app-manifest": "0.72.0",
"@clack/prompts": "1.7.0",
"oauth4webapi": "3.8.7",
"yaml": "2.9.0",
@@ -22,6 +23,8 @@
},
},
"packages": {
+ "@altertable/data-app-manifest": ["@altertable/data-app-manifest@0.72.0", "", { "dependencies": { "typescript": "5.9.3" } }, "sha512-404JXukgR2zGt52NbgDohuvtlx2kt8v54Yb8EWs2b2RjDKmOwQ2gnQJBQzAIUtsFu1Gup6awv4gc9qj7eazvPA=="],
+
"@babel/code-frame": ["@babel/code-frame@7.29.7", "", { "dependencies": { "@babel/helper-validator-identifier": "^7.29.7", "js-tokens": "^4.0.0", "picocolors": "^1.1.1" } }, "sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw=="],
"@babel/helper-validator-identifier": ["@babel/helper-validator-identifier@7.29.7", "", {}, "sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg=="],
@@ -332,6 +335,8 @@
"zod": ["zod@4.4.3", "", {}, "sha512-ytENFjIJFl2UwYglde2jchW2Hwm4GJFLDiSXWdTrJQBIN9Fcyp7n4DhxJEiWNAJMV1/BqWfW/kkg71UDcHJyTQ=="],
+ "@altertable/data-app-manifest/typescript": ["typescript@5.9.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw=="],
+
"tinyglobby/picomatch": ["picomatch@4.0.4", "", {}, "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A=="],
}
}
diff --git a/cli/package.json b/cli/package.json
index 934fbd8..6cf5bd0 100644
--- a/cli/package.json
+++ b/cli/package.json
@@ -48,6 +48,7 @@
"data-app:test:browser": "cd ../data-app/tests && bun run test"
},
"dependencies": {
+ "@altertable/data-app-manifest": "0.72.0",
"@clack/prompts": "1.7.0",
"oauth4webapi": "3.8.7",
"yaml": "2.9.0"
diff --git a/cli/scripts/smoke-data-app.ts b/cli/scripts/smoke-data-app.ts
index aa67c2e..80553e2 100644
--- a/cli/scripts/smoke-data-app.ts
+++ b/cli/scripts/smoke-data-app.ts
@@ -114,7 +114,7 @@ export async function smokeDataApp(command: string[], scaffoldOnly = false): Pro
"@altertable/data-app-react",
"@altertable/data-app-bun",
]) {
- if (manifest.dependencies?.[name] !== "0.71.0")
+ if (manifest.dependencies?.[name] !== "0.72.0")
throw new Error(`Packaged starter must pin ${name} to the tested release`);
}
for (const name of ["@altertable/data-app-embed", "@altertable/data-app-worker"]) {
diff --git a/cli/src/commands/app/dev.ts b/cli/src/commands/app/dev.ts
index c21d000..b6f4bab 100644
--- a/cli/src/commands/app/dev.ts
+++ b/cli/src/commands/app/dev.ts
@@ -1,3 +1,5 @@
+import { resolve } from "node:path";
+import { prepareFilePreview } from "@/commands/app/lib/file-dev.ts";
import { checkAppScope } from "@/commands/app/lib/scope.ts";
import { defineCommand } from "@/lib/command.ts";
import { CliError, EXIT_GENERIC } from "@/lib/errors.ts";
@@ -12,29 +14,44 @@ import {
export const appDevCommand = defineCommand({
metadata: {
name: "dev",
- description: "Preview a data app locally with lakehouse access.",
+ description:
+ "Preview a local data app directory, or a single-file data app, with lakehouse access.",
examples: [
"altertable app dev",
"altertable app dev --port 3022",
"altertable --profile staging app dev --dir ./my-app",
+ "altertable app dev --file ./index.tsx",
],
},
args: {
dir: { type: "string", description: "App directory (default: current directory)." },
- port: { type: "string", description: "Local dev server port (1–65535; default: app setting)." },
+ file: {
+ type: "string",
+ description:
+ "Path to a single-file React data app (index.tsx) to preview instead of --dir. Queries are declared in the file via defineDataApp.",
+ completion: "file",
+ },
+ port: {
+ type: "string",
+ description: "Local dev server port (1–65535; default: app setting, or 25837 for --file).",
+ },
},
async run({ args, execution, runtime }) {
assertAppOutputMode(runtime.context.json, runtime.context.agent);
- const port = appPort(args.port);
- const directory = appDirectory(args.dir);
+ const file = args.file === undefined ? undefined : appFile(args.file, args.dir);
+ const port = appPort(args.port) ?? (file ? "25837" : undefined);
+ const directory = file
+ ? await prepareFilePreview(file, execution.profile)
+ : appDirectory(args.dir);
requireAppScripts(directory, ["dev"]);
- await checkAppScope(directory, execution.profile);
- const installExitCode = await runAppCommand("install", directory);
+ if (!file) await checkAppScope(directory, execution.profile);
+ const installExitCode = await runAppCommand(file ? "install-frozen" : "install", directory);
if (installExitCode !== 0) return { exitCode: EXIT_GENERIC };
const proxy = startAppDevProxy(execution);
try {
const environment = {
...proxy.environment,
+ ...(file ? { ALTERTABLE_APP_FILE: file } : {}),
...(port ? { PORT: port } : {}),
};
const exitCode = await runAppCommand("dev", directory, environment);
@@ -45,6 +62,14 @@ export const appDevCommand = defineCommand({
},
});
+function appFile(file: unknown, dir: unknown): string {
+ if (dir !== undefined) throw new CliError("Pass either --dir or --file.");
+ if (typeof file !== "string" || file.length === 0) {
+ throw new CliError("--file requires a file path.");
+ }
+ return resolve(file);
+}
+
function appPort(value: unknown): string | undefined {
if (value === undefined) return undefined;
if (typeof value !== "string" || !/^[1-9]\d{0,4}$/.test(value) || Number(value) > 65535) {
diff --git a/cli/src/commands/app/index.test.ts b/cli/src/commands/app/index.test.ts
index 9b24241..b56ece3 100644
--- a/cli/src/commands/app/index.test.ts
+++ b/cli/src/commands/app/index.test.ts
@@ -179,4 +179,28 @@ describe("app commands", () => {
expect(build.exitCode).toBe(1);
expect(existsSync(join(directory, "build.json"))).toBe(false);
});
+
+ test("dev validates a single file before preparing its preview", async () => {
+ const file = workspace.writeFile(
+ "index.tsx",
+ `import { defineDataApp } from "@altertable/data-app";
+defineDataApp({ scope: { organization: "acme", environment: "staging" } });`,
+ );
+ async function failure(args: string[]): Promise {
+ return runAppCommand(["app", "dev", ...args]).catch((error: unknown) => error);
+ }
+ function message(text: string) {
+ return { message: expect.stringContaining(text) };
+ }
+
+ expect(await failure(["--file", file])).toMatchObject(message("data app file scope"));
+ expect(await failure(["--dir", directory, "--file", file])).toMatchObject(
+ message("either --dir or --file"),
+ );
+ expect(await failure(["--file", ""])).toMatchObject(message("--file requires a file path"));
+ expect(await failure(["--file", join(directory, "missing.tsx")])).toMatchObject(
+ message("Could not read source"),
+ );
+ expect(await failure(["--file", directory])).toMatchObject(message("Could not read source"));
+ });
});
diff --git a/cli/src/commands/app/index.ts b/cli/src/commands/app/index.ts
index e68e29d..7f43ecd 100644
--- a/cli/src/commands/app/index.ts
+++ b/cli/src/commands/app/index.ts
@@ -17,6 +17,7 @@ export const appCommand = defineCommand({
examples: [
"altertable app create my-app",
"altertable app dev",
+ "altertable app dev --file index.tsx",
"altertable app lint",
"altertable app build",
"altertable app upgrade",
diff --git a/cli/src/commands/app/lib/distribution.test.ts b/cli/src/commands/app/lib/distribution.test.ts
index 4985af4..07c5fc1 100644
--- a/cli/src/commands/app/lib/distribution.test.ts
+++ b/cli/src/commands/app/lib/distribution.test.ts
@@ -40,9 +40,9 @@ test("distribution embeds a deterministic starter with an exact package pin and
recommendedDataAppVersion(),
);
expect(JSON.parse(files["package.json"]!).dependencies).toMatchObject({
- "@altertable/data-app": "0.71.0",
- "@altertable/data-app-react": "0.71.0",
- "@altertable/data-app-bun": "0.71.0",
+ "@altertable/data-app": "0.72.0",
+ "@altertable/data-app-react": "0.72.0",
+ "@altertable/data-app-bun": "0.72.0",
});
expect(files["src/main.tsx"]).toContain('from "@altertable/data-app-react"');
expect(files["src/preview.ts"]).toContain('from "@altertable/data-app-bun/preview"');
diff --git a/cli/src/commands/app/lib/file-dev-server.ts.txt b/cli/src/commands/app/lib/file-dev-server.ts.txt
new file mode 100644
index 0000000..0ba47a5
--- /dev/null
+++ b/cli/src/commands/app/lib/file-dev-server.ts.txt
@@ -0,0 +1,17 @@
+import { localLakehouse } from "@altertable/data-app-bun";
+import { serveAppFile } from "@altertable/data-app-bun/preview";
+
+const preview = await serveAppFile({
+ file: process.env.ALTERTABLE_APP_FILE,
+ port: Number(process.env.PORT),
+ lakehouse: localLakehouse(),
+ resolveDependency: (specifier) => Bun.resolveSync(specifier, import.meta.dir),
+});
+
+for (const signal of ["SIGINT", "SIGTERM"]) {
+ process.once(signal, async () => {
+ await preview.stop();
+ process.exit(0);
+ });
+}
+console.log(`Data app running at ${preview.url} (${process.env.ALTERTABLE_APP_FILE})`);
diff --git a/cli/src/commands/app/lib/file-dev.test.ts b/cli/src/commands/app/lib/file-dev.test.ts
new file mode 100644
index 0000000..d709ec4
--- /dev/null
+++ b/cli/src/commands/app/lib/file-dev.test.ts
@@ -0,0 +1,64 @@
+import { rejects } from "node:assert/strict";
+import { existsSync } from "node:fs";
+import { readFile } from "node:fs/promises";
+import { join } from "node:path";
+import { afterEach, beforeEach, expect, test } from "bun:test";
+import { prepareFilePreview } from "@/commands/app/lib/file-dev.ts";
+import { dataAppPayload } from "@/commands/app/lib/payload.ts";
+import { FROM_ENV_PSEUDOPROFILE_NAME } from "@/lib/profile-store.ts";
+import { createLakehouseTestWorkspace } from "@/test-utils/lakehouse.ts";
+
+let workspace: ReturnType;
+let savedEnvironment: Record;
+beforeEach(() => {
+ savedEnvironment = {
+ ALTERTABLE_CONFIG_HOME: process.env.ALTERTABLE_CONFIG_HOME,
+ ALTERTABLE_ENV: process.env.ALTERTABLE_ENV,
+ };
+ workspace = createLakehouseTestWorkspace("file-dev");
+ process.env.ALTERTABLE_CONFIG_HOME = workspace.home;
+ process.env.ALTERTABLE_ENV = "production";
+});
+afterEach(() => {
+ workspace.cleanup();
+ for (const [key, value] of Object.entries(savedEnvironment)) {
+ if (value === undefined) delete process.env[key];
+ else process.env[key] = value;
+ }
+});
+
+function app(scope: string): string {
+ return `import { defineDataApp as define } from "@altertable/data-app";
+const app = define({ scope: ${scope}, queries: {} });`;
+}
+
+async function prepare(source: string): Promise {
+ const file = workspace.writeFile("index.tsx", source);
+ return prepareFilePreview(file, FROM_ENV_PSEUDOPROFILE_NAME);
+}
+
+test("prepares a reusable dev project from the released manifest without executing the app", async () => {
+ const directory = await prepare(
+ `${app('{ organization: "acme", environment: "production" }')}
+throw new Error("must not execute");`,
+ );
+ const manifest = JSON.parse(await readFile(join(directory, "package.json"), "utf8"));
+ const starter = JSON.parse(dataAppPayload.starter["package.json"]!);
+ expect(manifest.dependencies).toEqual(starter.dependencies);
+ expect(manifest.scripts).toEqual({ dev: "bun server.ts" });
+ expect(await readFile(join(directory, "bun.lock"), "utf8")).toBe(
+ dataAppPayload.starter["bun.lock"]!,
+ );
+ expect(await readFile(join(directory, "server.ts"), "utf8")).toContain(
+ "@altertable/data-app-bun/preview",
+ );
+ expect(await prepare(app('{ organization: "acme", environment: "production" }'))).toBe(directory);
+});
+
+test("rejects invalid declarations and mismatched scopes before creating the runtime", async () => {
+ await rejects(prepare("export const app = 1;"), /Could not extract the data app manifest\.\n1:/);
+ for (const scope of ["null", "{}", '{ organization: "acme", environment: "staging" }']) {
+ await rejects(prepare(app(scope)), /data app file scope does not match/);
+ }
+ expect(existsSync(join(workspace.home, "data-app-dev"))).toBe(false);
+});
diff --git a/cli/src/commands/app/lib/file-dev.ts b/cli/src/commands/app/lib/file-dev.ts
new file mode 100644
index 0000000..d6d71e6
--- /dev/null
+++ b/cli/src/commands/app/lib/file-dev.ts
@@ -0,0 +1,41 @@
+import { mkdir, writeFile } from "node:fs/promises";
+import { join } from "node:path";
+import serverScript from "@/commands/app/lib/file-dev-server.ts.txt";
+import { recommendedDataAppVersion } from "@/commands/app/lib/package.ts";
+import { dataAppPayload } from "@/commands/app/lib/payload.ts";
+import { readRequiredFile } from "@/commands/app/lib/remote.ts";
+import { assertAppScope, profileAppScope } from "@/commands/app/lib/scope.ts";
+import { configDir } from "@/lib/config-files.ts";
+import { ConfigurationError } from "@/lib/errors.ts";
+
+/** Prepare a regular dev project backed by the starter's pinned runtime. */
+export async function prepareFilePreview(file: string, profile: string): Promise {
+ const source = await readRequiredFile(file, "source");
+ // Keep the TypeScript compiler off the startup path of other CLI commands.
+ const { extractDataAppManifest } = await import("@altertable/data-app-manifest");
+ const { manifest, diagnostics } = extractDataAppManifest(source);
+ if (!manifest) {
+ const details = diagnostics
+ .slice(0, 3)
+ .map(({ message, start }) => `${start.line}:${start.column}: ${message}`)
+ .join("\n");
+ throw new ConfigurationError(`Could not extract the data app manifest.\n${details}`);
+ }
+ assertAppScope(manifest.scope, profileAppScope(profile), "data app file");
+
+ const directory = join(configDir(), "data-app-dev", recommendedDataAppVersion());
+ const starter = dataAppPayload.starter;
+ const packageJson = JSON.parse(starter["package.json"]!);
+ packageJson.scripts = { dev: "bun server.ts" };
+ await mkdir(directory, { recursive: true });
+ const files = {
+ "package.json": `${JSON.stringify(packageJson, null, 2)}\n`,
+ "bun.lock": starter["bun.lock"]!,
+ "bunfig.toml": starter["bunfig.toml"]!,
+ "server.ts": serverScript,
+ };
+ await Promise.all(
+ Object.entries(files).map(([name, content]) => writeFile(join(directory, name), content)),
+ );
+ return directory;
+}
diff --git a/cli/src/commands/app/lib/scope.ts b/cli/src/commands/app/lib/scope.ts
index 019d0e8..9e3fa15 100644
--- a/cli/src/commands/app/lib/scope.ts
+++ b/cli/src/commands/app/lib/scope.ts
@@ -8,6 +8,7 @@ import { ConfigurationError } from "@/lib/errors.ts";
export function assertAppScope(
scope: unknown,
profile: { organization?: string; organizationName?: string; environment?: string },
+ source = "app.json",
): void {
const value = scope as { organization?: unknown; environment?: unknown } | null;
if (
@@ -21,11 +22,21 @@ export function assertAppScope(
(Boolean(profile.environment) && value.environment !== profile.environment)
) {
throw new ConfigurationError(
- "app.json scope does not match the selected profile. Select the matching profile or update the app scope before querying.",
+ `${source} scope does not match the selected profile. Select the matching profile or update the app scope before querying.`,
);
}
}
+export function profileAppScope(profile: string) {
+ return {
+ organization: configGet("organization_slug", profile).trim(),
+ organizationName: configGet("organization_name", profile).trim(),
+ environment: isFromEnvProfile(profile)
+ ? readEnv("ALTERTABLE_ENV")
+ : configGet("api_key_env", profile).trim(),
+ };
+}
+
export async function checkAppScope(directory: string, profile: string): Promise {
let manifest;
try {
@@ -33,11 +44,5 @@ export async function checkAppScope(directory: string, profile: string): Promise
} catch {
throw new ConfigurationError("Cannot read a valid app.json for profile scope verification.");
}
- assertAppScope(manifest?.scope, {
- organization: configGet("organization_slug", profile).trim(),
- organizationName: configGet("organization_name", profile).trim(),
- environment: isFromEnvProfile(profile)
- ? readEnv("ALTERTABLE_ENV")
- : configGet("api_key_env", profile).trim(),
- });
+ assertAppScope(manifest?.scope, profileAppScope(profile));
}
diff --git a/data-app/starter/bun.lock b/data-app/starter/bun.lock
index 047bc1a..93b990c 100644
--- a/data-app/starter/bun.lock
+++ b/data-app/starter/bun.lock
@@ -5,9 +5,9 @@
"": {
"name": "data-app-starter",
"dependencies": {
- "@altertable/data-app": "0.71.0",
- "@altertable/data-app-bun": "0.71.0",
- "@altertable/data-app-react": "0.71.0",
+ "@altertable/data-app": "0.72.0",
+ "@altertable/data-app-bun": "0.72.0",
+ "@altertable/data-app-react": "0.72.0",
"react": "19.3.0",
"react-dom": "19.3.0",
},
@@ -23,11 +23,11 @@
},
},
"packages": {
- "@altertable/data-app": ["@altertable/data-app@0.71.0", "", { "dependencies": { "@internationalized/date": "3.12.4" } }, "sha512-2v4vy3BJnKHFp7LJ60xwSipBrwZED+6v+iFKmKYy0k3hHEf5iUjApR7NwUJVNC5dJxDoQPLGLesQZrA18VoOuw=="],
+ "@altertable/data-app": ["@altertable/data-app@0.72.0", "", { "dependencies": { "@internationalized/date": "3.12.4" } }, "sha512-F1wgk5ANgxrl2y48w2D0PpWkv8SHTiPapBbmGrlrb4OQjgj2JAjmitVBUW/luMj0M3E7hwVAjOvld4JT6KbloQ=="],
- "@altertable/data-app-bun": ["@altertable/data-app-bun@0.71.0", "", { "dependencies": { "@altertable/data-app": "0.71.0", "@altertable/lakehouse": "0.4.1", "get-tsconfig": "4.14.3" } }, "sha512-uxYbvGeWhfRAVfdWAHWDKDW17csmpQocIK/STewR5Cb+X7HS51CJY/hdXSKXBBMsejMH6CW69oy49PBOnq1rTw=="],
+ "@altertable/data-app-bun": ["@altertable/data-app-bun@0.72.0", "", { "dependencies": { "@altertable/data-app": "0.72.0", "@altertable/lakehouse": "0.4.1", "get-tsconfig": "4.14.3" } }, "sha512-fMjSn8TIBo5oSQbimlHHyfUauZ/xxKvKCl7Jze7xUrIPSLccZXAesHjBIHwoKmKjXstBheWp47asrjooN5pLgw=="],
- "@altertable/data-app-react": ["@altertable/data-app-react@0.71.0", "", { "dependencies": { "@altertable/data-app": "0.71.0", "@floating-ui/react": "0.27.20", "@internationalized/date": "3.12.4", "@tanstack/react-query": "5.104.0", "fflate": "0.8.3", "fuzzysort": "4.0.2", "html-to-image": "1.11.13", "lucide-react": "1.48.0", "react-aria-components": "1.21.1", "recharts": "3.10.1" }, "peerDependencies": { "react": ">=19.2.0", "react-dom": ">=19.2.0" } }, "sha512-1qT4h94ZUWUh6dkJnqpo1a+b0HNSdZeu6Fs32bIQQy/qZyevPhuE0HKK2O6pEgzcQmYJPlUKmxTn7HquKtprNQ=="],
+ "@altertable/data-app-react": ["@altertable/data-app-react@0.72.0", "", { "dependencies": { "@altertable/data-app": "0.72.0", "@floating-ui/react": "0.27.20", "@internationalized/date": "3.12.4", "@tanstack/react-query": "5.104.0", "fflate": "0.8.3", "fuzzysort": "4.0.2", "html-to-image": "1.11.13", "lucide-react": "1.48.0", "react-aria-components": "1.21.1", "recharts": "3.10.1" }, "peerDependencies": { "react": ">=19.2.0", "react-dom": ">=19.2.0" } }, "sha512-SEJ3tHdZ6oUZm+pJLiesfnknYQfSd3/Aymhip3qA08gu3uJCQ1I2ocXLmzj6zcZZXFmtDwGhkWprVGXiomtxGA=="],
"@altertable/lakehouse": ["@altertable/lakehouse@0.4.1", "", {}, "sha512-m7d15cWt+WUGW7lVw2KYGD+Se8MzO25G7SWSuFd+OasBxWmOJNa2IrgvOHGVEbnZ+kexTUy9NjAGQ69sG4V91w=="],
diff --git a/data-app/starter/package.json b/data-app/starter/package.json
index ac9b6f6..389733e 100644
--- a/data-app/starter/package.json
+++ b/data-app/starter/package.json
@@ -15,9 +15,9 @@
"build": "bun build src/index.html --outdir=dist --production"
},
"dependencies": {
- "@altertable/data-app": "0.71.0",
- "@altertable/data-app-react": "0.71.0",
- "@altertable/data-app-bun": "0.71.0",
+ "@altertable/data-app": "0.72.0",
+ "@altertable/data-app-bun": "0.72.0",
+ "@altertable/data-app-react": "0.72.0",
"react": "19.3.0",
"react-dom": "19.3.0"
},
diff --git a/data-app/tests/bun.lock b/data-app/tests/bun.lock
index e327efa..6f2b44b 100644
--- a/data-app/tests/bun.lock
+++ b/data-app/tests/bun.lock
@@ -5,7 +5,7 @@
"": {
"name": "data-app-browser-tests",
"dependencies": {
- "@altertable/data-app": "0.71.0",
+ "@altertable/data-app": "0.72.0",
},
"devDependencies": {
"@playwright/test": "1.63.0",
@@ -16,7 +16,7 @@
},
},
"packages": {
- "@altertable/data-app": ["@altertable/data-app@0.71.0", "", { "dependencies": { "@internationalized/date": "3.12.4" } }, "sha512-2v4vy3BJnKHFp7LJ60xwSipBrwZED+6v+iFKmKYy0k3hHEf5iUjApR7NwUJVNC5dJxDoQPLGLesQZrA18VoOuw=="],
+ "@altertable/data-app": ["@altertable/data-app@0.72.0", "", { "dependencies": { "@internationalized/date": "3.12.4" } }, "sha512-F1wgk5ANgxrl2y48w2D0PpWkv8SHTiPapBbmGrlrb4OQjgj2JAjmitVBUW/luMj0M3E7hwVAjOvld4JT6KbloQ=="],
"@internationalized/date": ["@internationalized/date@3.12.4", "", { "dependencies": { "@swc/helpers": "^0.5.0" } }, "sha512-M1dEn4c1U1HsSlaVR8upZtSqvXrTkHDfv18H01uCSJyjVLDxnBR38v/fMxecmlwXKR4i9HeZcmgQAPE6A+aGJQ=="],
diff --git a/data-app/tests/package.json b/data-app/tests/package.json
index d012dc6..ec16dee 100644
--- a/data-app/tests/package.json
+++ b/data-app/tests/package.json
@@ -15,6 +15,6 @@
"typescript": "7.0.2"
},
"dependencies": {
- "@altertable/data-app": "0.71.0"
+ "@altertable/data-app": "0.72.0"
}
}